source: sans/SANSReduction/trunk/Put in User Procedures/SANS_Reduction_v5.00/ProtocolAsPanel.ipf @ 47

Last change on this file since 47 was 47, checked in by srkline, 16 years ago

bug fixes and performance tweaks

File size: 78.3 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=5.0
3#pragma IgorVersion=4.0
4
5//************************
6//      Vers. 1.2 092101
7//
8//7/2001 converted protocols to simply use the filenames, rather than the path:filename
9//this should allow portability of the protocols between machines
10//**ALL** protocols now depend on the path "catPathName"
11//
12//procedure files for construction of protocols interactively,
13//selecting files from the CAT/VSHORT table, rather than picking blindly
14//from a dialog - the process of selecting/setting files is not as
15//transparent as it could be for new users
16//
17//*************************
18//////////////////////////////////
19//
20//              KEYWORD=<value> lists used in protocol definitions
21//
22//              KEYWORDS are ALWAYS capitalized, and yes, it does matter
23//
24//              for ABSOLUTE parameters
25//              (4) possible keywords, all with numerical values
26//              TSTAND=value            transmission of the standard
27//              DSTAND=value            thickness of the standard, in centimeters
28//              IZERO=value             I(q=0) value for the standard, in normalized neutron counts
29//              XSECT=value             calibrated cross-section of the standard sample
30//
31//              For calibration with a transmission file, set TSTAND, DSTAND, and XSECT to 1.0
32//              and set IZERO to KAPPA (defined in Tania's handout, or in documentation of MRED_KAP on VAX)
33//
34//
35//              For AVERAGE and for DRAWING
36//                      DRAWING routines only use a subset of the total list, since saving, naming, etc. don't apply
37//              (10) possible keywords, some numerical, some string values
38//              AVTYPE=string           string from set {Circular,Annular,Rectangular,Sector,2D_ASCII,QxQy_ASCII,PNG_Graphic}
39//              PHI=value                       azimuthal angle (-90,90)
40//              DPHI=value                      +/- angular range around phi for average
41//              WIDTH=value             total width of rectangular section, in pixels
42//              SIDE=string             string from set {left,right,both} **note NOT capitalized
43//              QCENTER=value           q-value (1/A) of center of annulus for annular average
44//              QDELTA=value            total width of annulus centered at QCENTER
45//              PLOT=string             string from set {Yes,No} = truth of generating plot of averaged data
46//              SAVE=string             string from set {Yes,No} = truth of saving averaged data to disk
47//              NAME=string             string from set {Auto,Manual} = Automatic name generation or Manual(dialog)
48//
49//
50//              For work.DRK usage:
51//              **the list is COMMA delimited, soparator is =
52//              DRK=none,DRKMODE=0,
53//              DRK=name                        is the name of the file, must be a full name, expected to be raw data
54//              DRKMODE=value           is a numeric value (0 or 10 to add to the Correct(mode) switch (unused?)
55//
56//////////////////////////////////
57
58
59//main entry procedure for initialzing and displaying the protocol panel
60// initilaizes folders and globals as needed
61//
62Proc ReductionProtocolPanel()
63        DoWindow/F ProtocolPanel
64        if(V_flag==0)
65                InitProtocolPanel()
66                ProtocolPanel()
67        Endif
68End
69
70//initialization procedure for the protocol panel
71//note that :gAbsStr is also shared (common global) to that used in
72//the questionnare form of the protcol (see protocol.ipf)
73//
74//0901, uses 8 points in protocol wave
75Proc InitProtocolPanel()
76
77        //set up the global variables needed for the protocol panel
78        //global strings to put in a temporary protocol textwave
79        Variable ii=0,nsteps=8
80        String waveStr="tempProtocol"
81        SetDataFolder root:myGlobals:Protocols
82        Make/O/T/N=(nsteps) $"root:myGlobals:Protocols:tempProtocol"
83        do
84                $"root:myGlobals:Protocols:tempProtocol"[ii] = ""
85                ii+=1
86        while(ii<nsteps)
87        String/G root:myGlobals:Protocols:gSAM="ask"
88        String/G root:myGlobals:Protocols:gBGD="ask"
89        String/G root:myGlobals:Protocols:gEMP="ask"
90        String/G root:myGlobals:Protocols:gDIV="ask"
91        String/G root:myGlobals:Protocols:gMASK="ask"
92        String/G root:myGlobals:Protocols:gAbsStr="ask"
93        String/G root:myGlobals:Protocols:gAVE="AVTYPE=Circular;SAVE=Yes;NAME=Auto;PLOT=Yes;"
94        String/G root:myGlobals:Protocols:gDRK="DRK=none,DRKMODE=0,"
95       
96        SetDataFolder root:
97       
98End
99
100//button control to create a CAT/SHORT notebook listing of all data files
101//in the selected folder (catPathName)
102//
103Function DoCatShort(ctrlName) : ButtonControl
104        String ctrlName
105
106        Execute "BuildCatVeryShortTable()"
107       
108End
109
110//button procedure to reset the panel seletctions/checks...etc...
111//to reflect the choices in a previously saved protocol
112// - parses through the protocol and resets the appropriate global strings and
113//updates the panel display
114//
115Function RecallProtocolButton(ctrlName) : ButtonControl
116        String ctrlName
117
118        //will reset panel values based on a previously saved protocol
119        //pick a protocol wave from the Protocols folder
120        //MUST move to Protocols folder to get wavelist
121        SetDataFolder root:myGlobals:Protocols
122        Execute "PickAProtocol()"
123       
124        //get the selected protocol wave choice through a global string variable
125        SVAR protocolName = root:myGlobals:Protocols:gProtoStr
126
127        //If "CreateNew" was selected, ask user to try again
128        if(cmpstr("CreateNew",protocolName) == 0)
129                Abort "CreateNew is for making a new Protocol. Select a previously saved Protocol"
130        Endif
131       
132        //reset the panel based on the protocol textwave (currently a string)
133        ResetToSavedProtocol(protocolName)
134       
135        SetDataFolder root:
136        return(0)
137End
138
139//deletes the selected protocol from the list and from memory
140//
141Function DeleteProtocolButton(ctrlName) : ButtonControl
142        String ctrlName
143
144        //put up a list of protocols and pick one
145        SetDataFolder root:myGlobals:Protocols
146//      Execute "DeleteAProtocol()"
147        String Protocol=""
148        Prompt Protocol "Delete A Protocol",popup, DeletableProtocols()
149        DoPrompt "Select protocol to delete",protocol
150        If(V_flag==1)
151                return(0)
152        endif
153
154        //If "CreateNew, Base, DoAll, or tempProtocol" was selected, do nothing
155        strswitch(protocol)
156                case "CreateNew":
157                        break
158                case "DoAll":
159                        break
160                case "Base":
161                        break
162                case "tempProtocol":
163                        break
164                default:
165                        //delete the protocol
166                        KillWaves/Z $protocol
167        endswitch
168       
169        SetDataFolder root:
170        return(0)
171End
172
173
174//function that actually parses the protocol specified by nameStr
175//which is just the name of the wave, without a datafolder path
176//
177Function ResetToSavedProtocol(nameStr)
178        String nameStr
179       
180        //allow special cases of Base and DoAll Protocols to be recalled to panel - since they "ask"
181        //and don't need paths
182       
183        String catPathStr
184        PathInfo catPathName
185        catPathStr=S_path
186       
187        //SetDataFolder root:myGlobals:Protocols                //on windows, data folder seems to get reset (erratically) to root:
188        Wave/T w=$("root:myGlobals:Protocols:" + nameStr)
189       
190        String fullPath="",comma=",",list="",nameList="",PathStr="",item=""
191        Variable ii=0,numItems,checked,specialProtocol
192       
193        if((cmpstr(nameStr,"Base")==0) || (cmpstr(nameStr,"DoAll")==0))
194                specialProtocol = 1
195        else
196                specialProtocol = 0
197        Endif
198       
199        //background
200        checked = 1
201        nameList = w[0]
202        If(cmpstr(nameList,"none") ==0)
203                checked = 0
204        Endif
205//      numItems = ItemsInList(list,comma)
206//      nameList = ""
207//      ii=0
208//      checked = 1
209//      do
210//              fullPath = StringFromList(ii,list,comma)
211//              PathStr = GetPathStrFromFullName(fullPath)
212//              item = GetFileNameFromPathKeepSemi(fullPath)
213//              nameList += item+comma
214//              If(cmpstr(item,"none") ==0)
215//                      nameList = item
216//                      checked = 0
217//                      break
218//              Endif
219//              If(cmpstr(item,"ask") ==0)
220//                      nameList = item
221//                      checked = 1
222//                      break
223//              Endif
224//              if((cmpstr(pathStr,catPathStr) != 0) %& !(specialProtocol))
225//                      Print "pathstr = ",pathStr
226//                      Print "catPathStr = ",catPathStr
227//                      Abort "saved protocol path and CAT path do not match - reset CAT/SHORT to pathStr"
228//              Endif
229//              ii+=1
230//      while(ii<numItems)
231        //set the global string to display and checkbox
232        String/G root:myGlobals:Protocols:gBGD = nameList
233        CheckBox prot_check win=ProtocolPanel,value=checked
234       
235        //empty
236        checked = 1
237        nameList = w[1]
238        If(cmpstr(nameList,"none") ==0)
239                checked = 0
240        Endif
241//      numItems = ItemsInList(list,comma)
242//      nameList = ""
243//      ii=0
244//      checked = 1
245//      do
246//              fullPath = StringFromList(ii,list,comma)
247//              PathStr = GetPathStrFromFullName(fullPath)
248//              item = GetFileNameFromPathKeepSemi(fullPath)
249//              nameList += item+comma
250//              If(cmpstr(item,"none") ==0)
251//                      nameList = item
252//                      checked = 0
253//                      break
254//              Endif
255//              If(cmpstr(item,"ask") ==0)
256//                      nameList = item
257//                      checked = 1
258//                      break
259//              Endif
260//              if((cmpstr(pathStr,catPathStr) != 0) %& !(specialProtocol))
261//                      Print "pathstr = ",pathStr
262//                      Print "catPathStr = ",catPathStr
263//                      Abort "saved protocol path and CAT path do not match"
264//              Endif
265//              ii+=1
266//      while(ii<numItems)
267        //set the global string to display and checkbox
268        String/G root:myGlobals:Protocols:gEMP = nameList
269        CheckBox prot_check_1 win=ProtocolPanel,value=checked
270       
271        //DIV file
272        checked = 1
273        nameList = w[2]
274        If(cmpstr(nameList,"none") ==0)
275                checked = 0
276        Endif
277//      list = w[2]
278//      numItems = ItemsInList(list,comma)
279//      nameList = ""
280//      ii=0
281//      checked = 1
282//      do
283//              fullPath = StringFromList(ii,list,comma)
284//              PathStr = GetPathStrFromFullName(fullPath)
285//              item = GetFileNameFromPathKeepSemi(fullPath)
286//              nameList += item+comma
287//              If(cmpstr(item,"none") ==0)
288//                      nameList = item
289//                      checked = 0
290//                      break
291//              Endif
292//              If(cmpstr(item,"ask") ==0)
293//                      nameList = item
294//                      checked = 1
295//                      break
296//              Endif
297//              if((cmpstr(pathStr,catPathStr) != 0) %& !(specialProtocol))
298//                      Print "pathstr = ",pathStr
299//                      Print "catPathStr = ",catPathStr
300//                      Abort "saved protocol path and CAT path do not match"
301//              Endif
302//              ii+=1
303//      while(ii<numItems)
304        //set the global string to display and checkbox
305        String/G root:myGlobals:Protocols:gDIV = nameList
306        CheckBox prot_check_2 win=ProtocolPanel,value=checked
307       
308        //Mask file
309        checked = 1
310        nameList = w[3]
311        If(cmpstr(nameList,"none") ==0)
312                checked = 0
313        Endif
314//      list = w[3]
315//      numItems = ItemsInList(list,comma)
316//      nameList = ""
317//      ii=0
318//      checked = 1
319//      do
320//              fullPath = StringFromList(ii,list,comma)
321//              PathStr = GetPathStrFromFullName(fullPath)
322//              item = GetFileNameFromPathKeepSemi(fullPath)
323//              nameList += item+comma
324//              If(cmpstr(item,"none") ==0)
325//                      nameList = item
326//                      checked = 0
327//                      break
328//              Endif
329//              If(cmpstr(item,"ask") ==0)
330//                      nameList = item
331//                      checked = 1
332//                      break
333//              Endif
334//              if((cmpstr(pathStr,catPathStr) != 0) %& !(specialProtocol))
335//                      Print "pathstr = ",pathStr
336//                      Print "catPathStr = ",catPathStr
337//                      Abort "saved protocol path and CAT path do not match"
338//              Endif
339//              ii+=1
340//      while(ii<numItems)
341        //set the global string to display and checkbox
342        String/G root:myGlobals:Protocols:gMASK = nameList
343        CheckBox prot_check_3 win=ProtocolPanel,value=checked
344       
345        //4 = abs parameters
346        list = w[4]
347        numItems = ItemsInList(list,";")
348        checked = 1
349        if(numitems == 4)
350                //correct number of parameters, assume ok
351                String/G root:myGlobals:Protocols:gAbsStr = list
352                CheckBox prot_check_9 win=ProtocolPanel,value=checked
353        else
354                item = StringFromList(0,list,";")
355                if(cmpstr(item,"none")==0)
356                        checked = 0
357                        list = "none"
358                        String/G root:myGlobals:Protocols:gAbsStr = list
359                        CheckBox prot_check_9 win=ProtocolPanel,value=checked
360                else
361                        //force to "ask"
362                        checked = 1
363                        String/G root:myGlobals:Protocols:gAbsStr = "ask"
364                        CheckBox prot_check_9 win=ProtocolPanel,value=checked
365                Endif
366        Endif
367       
368        //5 = averaging choices
369        list = w[5]
370        item = StringByKey("AVTYPE",list,"=",";")
371        if(cmpstr(item,"none") == 0)
372                checked = 0
373                String/G root:myGlobals:Protocols:gAVE = "none"
374                CheckBox prot_check_5 win=ProtocolPanel,value=checked
375        else
376                checked = 1
377                String/G root:myGlobals:Protocols:gAVE = list
378                CheckBox prot_check_5 win=ProtocolPanel,value=checked
379        Endif
380       
381        //6 = DRK choice
382        list = w[6]
383        item = StringByKey("DRK",list,"=",",")
384        //print list,item
385        if(cmpstr(item,"none") == 0)
386                checked = 0
387                String/G root:myGlobals:Protocols:gDRK = list
388                CheckBox prot_check_6 win=ProtocolPanel,value=checked
389        else
390                checked = 1
391                String/G root:myGlobals:Protocols:gDRK = list
392                CheckBox prot_check_6 win=ProtocolPanel,value=checked
393        Endif
394       
395        //7 = unused
396       
397        //all has been reset, get out
398        Return (0)
399End
400
401//button action procedure that simply closes the panel
402//
403Function DoneProtocolButton(ctrlName) : ButtonControl
404        String ctrlName
405
406        //will gracefully close and exit the protocol panel
407       
408        DoWindow/K ProtocolPanel
409End
410
411//button action procedure that saves the current choices on the panel
412//as a named protocol, for later recall
413//asks for a valid name, then creates a protocol from the panel choices
414//creates a wave, and sets the current protocol name to this new protocol
415//
416//now allows the user the choice to overwrite a protocol
417//
418Function SaveProtocolButton(ctrlName) : ButtonControl
419        String ctrlName
420
421        Variable notDone=1, newProto=1
422        //will prompt for protocol name, and save the protocol as a text wave
423        //prompt for name of new protocol wave to save
424        do
425                Execute "AskForName()"
426                SVAR newProtocol = root:myGlobals:Protocols:gNewStr
427               
428                //make sure it's a valid IGOR name
429                newProtocol = CleanupName(newProtocol,0)        //strict naming convention
430                String/G root:myGlobals:Protocols:gNewStr=newProtocol           //reassign, if changed
431                Print "newProtocol = ",newProtocol
432               
433                SetDataFolder root:myGlobals:Protocols
434                if(WaveExists( $("root:myGlobals:Protocols:" + newProtocol) ) == 1)
435                        //wave already exists
436                        DoAlert 1,"That name is already in use. Do you wish to overwrite the existing protocol?"
437                        if(V_Flag==1)
438                                notDone = 0
439                                newProto = 0
440                        else
441                                notDone = 1
442                        endif
443                else
444                        //name is good
445                        notDone = 0
446                Endif
447        while(notDone)
448       
449        //current data folder is  root:myGlobals:Protocols
450        if(newProto)
451                Make/O/T/N=8 $("root:myGlobals:Protocols:" + newProtocol)
452        Endif
453       
454        MakeProtocolFromPanel( $("root:myGlobals:Protocols:" + newProtocol) )
455        String/G  root:myGlobals:Protocols:gProtoStr = newProtocol
456       
457        //the data folder WAS changed above, this must be reset to root:
458        SetDatafolder root:
459End
460
461//function that does the guts of reading the panel controls and globals
462//to create the necessary text fields for a protocol
463//Wave/T w (input) is an empty text wave of 8 elements for the protocol
464//on output, w[] is filled with the protocol strings as needed from the panel
465//
466Function MakeProtocolFromPanel(w)
467        Wave/T w
468       
469        //construct the protocol text wave form the panel
470        //it is to be parsed by ExecuteProtocol() for the actual data reduction
471        PathInfo catPathName                    //this is where the files came from
472        String pathstr=S_path,tempStr,curList
473        Variable checked,ii,numItems
474       
475        //look for checkbox, then take each item in list and prepend the path
476        //w[0] = background
477        ControlInfo/W=ProtocolPanel prot_check
478        checked = V_value
479        if(checked)
480                //build the list
481                //just read the global
482                SVAR str=root:myGlobals:Protocols:gBGD
483                if(cmpstr(str,"ask")==0)
484                        w[0] = str              //just ask
485                else
486                        tempstr = ParseRunNumberList(str)
487                        if(strlen(tempStr)==0)
488                                return(1)                               //error parsing list
489                        else
490                                w[0] = tempstr
491                                str = tempstr           //set the protocol and the global
492                        endif
493                endif
494        else
495                //none used - set textwave (and global?)
496                w[0] = "none"
497                String/G root:myGlobals:Protocols:gBGD = "none"
498        endif
499       
500        //w[1] = empty
501        ControlInfo/W=ProtocolPanel prot_check_1
502        checked = V_value
503        if(checked)
504                //build the list
505                //just read the global
506                SVAR str=root:myGlobals:Protocols:gEMP
507                if(cmpstr(str,"ask")==0)
508                        w[1] = str
509                else
510                        tempstr = ParseRunNumberList(str)
511                        if(strlen(tempStr)==0)
512                                return(1)
513                        else
514                                w[1] = tempstr
515                                str=tempStr
516                        endif
517                endif
518        else
519                //none used - set textwave (and global?)
520                w[1] = "none"
521                String/G root:myGlobals:Protocols:gEMP = "none"
522        endif
523       
524        //w[2] = div file
525        ControlInfo/W=ProtocolPanel prot_check_2
526        checked = V_value
527        if(checked)
528                //build the list
529                //just read the global
530                SVAR str=root:myGlobals:Protocols:gDIV
531                if(cmpstr(str,"ask")==0)
532                        w[2] = str
533                else
534                        tempStr = ParseRunNumberList(str)
535                        if(strlen(tempStr)==0)
536                                return(1)
537                        else
538                                w[2] = tempstr
539                                str=tempstr
540                        endif
541                endif
542        else
543                //none used - set textwave (and global?)
544                w[2] = "none"
545                String/G root:myGlobals:Protocols:gDIV = "none"
546        endif
547       
548        //w[3] = mask file
549        ControlInfo/W=ProtocolPanel prot_check_3
550        checked = V_value
551        if(checked)
552                //build the list
553                //just read the global
554                SVAR str=root:myGlobals:Protocols:gMASK
555                if(cmpstr(str,"ask")==0)
556                        w[3] = str
557                else
558                        tempstr = ParseRunNumberList(str)
559                        if(strlen(tempstr)==0)
560                                return(1)
561                        else
562                                w[3] = tempstr
563                                str = tempstr
564                        endif
565                endif
566        else
567                //none used - set textwave (and global?)
568                w[3] = "none"
569                String/G root:myGlobals:Protocols:gMASK = "none"
570        endif
571       
572        //w[4] = abs parameters
573        ControlInfo/W=ProtocolPanel prot_check_9
574        checked = V_value
575        if(checked)
576                //build the list
577                //just read the global
578                SVAR str=root:myGlobals:Protocols:gAbsStr
579                w[4] = str
580        else
581                //none used - set textwave (and global?)
582                w[4] = "none"
583                String/G root:myGlobals:Protocols:gAbsStr = "none"
584        endif
585       
586        //w[5] = averaging choices
587        ControlInfo/W=ProtocolPanel prot_check_5                        //do the average?
588        checked = V_value
589        if(checked)
590                //just read the global
591                SVAR avestr=root:myGlobals:Protocols:gAVE
592                w[5] = avestr
593        else
594                //none used - set textwave
595                w[5] = "AVTYPE=none;"
596        endif
597       
598        //w[6]
599        //work.DRK information
600        SVAR drkStr=root:myGlobals:Protocols:gDRK
601        w[6] = drkStr
602       
603        //w[7]
604        //currently unused
605        w[7] = ""
606       
607        return(0)
608End
609
610//********UNUSED************
611//7/2001 - plan to modify this function to parse the comma-delimited list, (possibly just run numbers)
612//and return a valid comma-delimited list of full filenames (no paths)
613//
614//function that takes a comma separated list of filenames (without path or version)
615//and returns a full list of path;name;vers (comma delimited)
616//that is needed for the protocol, which is expecting the full path
617//to directly open the file(s) in the list
618//this function checks for the existence of files before adding to the list
619//pathStr (input) is the path (as returned by pathInfo)
620//
621Function/S BuildList(list,pathstr)
622        String list,pathstr
623       
624        //input list is probably just filename, no version number
625        //COMMA separated lists, since file names will (MAY) include semicolon version numbers
626        //find the file and version number - so that full path:file;vers for each item
627        //trailing comma OK at end of list, ExecuteProtocol() treats all as lists
628       
629        String newList="",separator=",",tempstr="",partialName=""
630        Variable ii=0,numitems
631       
632        numitems = ItemsInList(list,separator)
633        do
634                tempstr = StringFromList(ii,list,separator)
635                if(cmpstr(tempstr,"ask")==0)
636                                newList = tempstr                                       //don't prepend path to "ask" option, no comma
637                                break                                                           //get out - don't add anything else to list
638                endif
639                if(strlen(tempStr)!=0)          //skip any null items
640                        //add version number (if needed) and make sure the filename is valid
641                        partialName = FindValidFilename(tempStr)
642                        //can't check for RAW here - may be dealing with mask, div ... or other filetypes
643                        newList += pathstr+partialName+separator
644                endif
645                ii+=1
646        while(ii<numitems)
647       
648        Return(newlist)
649       
650End
651
652
653//button control function to set the background (SAM) file name to the
654//selected name in the CAT/SHORT window
655//the version number of the file need not be selected, it will be added later if needed
656//multiple SAMple files can be added together if the list is not reset
657//
658Function PickSAMButton(ctrlName) : ButtonControl
659        String ctrlName
660
661        //set the SAM file(s) as a global string
662        //multiple files are added as a COMMA separated list of files, w/extension
663        //global string is either null or contains filename(s) on entry
664       
665        //ask to reset the list?
666        DoAlert 1,"Reset the list of sample files?"
667        if(V_flag == 1)
668                String/G root:myGlobals:Protocols:gSAM = ""
669        Endif
670       
671        Variable catVSTableExists, num_sans_files
672        catVSTableExists = WinType("catVSTable")
673        //??BUG?? V_flag returns 1 even if no selection?
674        //check manually for null selection
675        //Print "local v_flag = ",num2str(V_flag)
676        Wave/T LocFilenames = $"root:myGlobals:CatVSHeaderInfo:Filenames"
677        if (catVSTableExists != 0)
678                GetSelection table,CatVSTable,7
679                if(strsearch(S_selection,"Filenames",0) == 0)
680                   //selection OK, add to list
681          Duplicate/O/R=[V_startRow,V_endRow] LocFilenames, filenames
682          Wave/T selectedFiles = $"filenames"
683          num_sans_files = numpnts(selectedFiles)
684                   SVAR temp = root:myGlobals:Protocols:gSAM
685          Variable ii=0
686          do
687            temp = temp+selectedFiles[ii]+","
688            ii+=1
689          while (ii < num_sans_files)
690      Else
691                                DoAlert 0,"Invalid selection from the File Catalog window"
692      Endif
693        else
694                //no selection
695                String/G root:myGlobals:Protocols:gSAM = "ask"
696                DoAlert 0,"No file selected from File Catalog table or no File Catalog table available"
697        Endif
698        return(0)
699End
700
701//button control to set the background (BGD) file name to the
702//selected name in the CAT/SHORT window
703//the version number of the file need not be selected, it will be added later if needed
704//multiple BGD files can be added together if the file list is not reset
705//
706Function PickBGDButton(ctrlName) : ButtonControl
707        String ctrlName
708
709        //set the BGD file(s) as a global string
710        //multiple files are added as a COMMA separated list of files, w/extension
711        //global string is either null or contains filename(s) on entry
712       
713        //ask to reset the list?
714        DoAlert 1,"Reset the list of background files?"
715        if(V_flag == 1)
716                String/G root:myGlobals:Protocols:gBGD = ""
717        Endif
718
719        Variable catVSTableExists, num_sans_files
720        catVSTableExists = WinType("CatVSTable")
721        //??BUG?? V_flag returns 1 even if no selection?
722        //check manually for null selection
723        //Print "local v_flag = ",num2str(V_flag)
724        Wave/T LocFilenames = $"root:myGlobals:CatVSHeaderInfo:Filenames"
725        if (catVSTableExists != 0)
726                GetSelection table,CatVSTable,7
727                if(strsearch(S_selection,"Filenames",0) == 0)
728           //selection OK, add to list
729                   Duplicate/O/R=[V_startRow,V_endRow] LocFilenames, filenames
730                   Wave/T selectedFiles = $"filenames"
731                   num_sans_files = numpnts(selectedFiles)
732                   SVAR temp = root:myGlobals:Protocols:gBGD
733                        Variable ii=0
734                        do
735                                temp = temp+selectedFiles[ii]+","
736                                ii+=1
737                        while (ii < num_sans_files)
738                Else
739                        DoAlert 0,"Invalid selection from the File Catalog table"
740                Endif
741        else
742                //no selection
743                DoAlert 0,"No file selected from File Catalog table or no File Catalog table available"
744        Endif
745       
746End
747
748//button control function to set the background (EMP) file name to the
749//selected name in the CAT/SHORT window
750//the version number of the file need not be selected, it will be added later if needed
751//multiple EMP files can be added together if the file list is not reset
752//
753Function PickEMPButton(ctrlName) : ButtonControl
754        String ctrlName
755
756        //ask to reset the list?
757        DoAlert 1,"Reset the list of empty cell files?"
758        if(V_flag == 1)
759                String/G root:myGlobals:Protocols:gEMP = ""
760        Endif
761       
762        Variable catVSTableExists, num_sans_files
763        catVSTableExists = WinType("catVSTable")
764        //??BUG?? V_flag returns 1 even if no selection?
765        //check manually for null selection
766        //Print "local v_flag = ",num2str(V_flag)
767        Wave/T LocFilenames = $"root:myGlobals:CatVSHeaderInfo:Filenames"
768        if (catVSTableExists != 0)
769                GetSelection table,CatVSTable,7
770                if(strsearch(S_selection,"Filenames",0) == 0)
771                   //selection OK, add to list
772                Duplicate/O/R=[V_startRow,V_endRow] LocFilenames, filenames
773        Wave/T selectedFiles = $"filenames"
774                num_sans_files = numpnts(selectedFiles)
775                SVAR temp = root:myGlobals:Protocols:gEMP
776                        Variable ii=0
777                        do
778                                temp = temp+selectedFiles[ii]+","
779                                ii+=1
780                        while (ii < num_sans_files)
781                Else
782                        DoAlert 0,"Invalid selection from the File Catalog table"
783                Endif
784        else
785                //no selection
786                DoAlert 0,"No file selected from File Catalog table or no File Catalog table available"
787        Endif
788       
789End
790
791//button control function to set the background (DIV) file name to the
792//selected name in the CAT/SHORT window
793//the version number of the file need not be selected, it will be added later if needed
794//there can only be one DIV file for a given protocol
795//
796Function PickDIVButton(ctrlName) : ButtonControl
797        String ctrlName
798
799        //alwys reset the list of DIV files, there can be only one
800        String/G root:myGlobals:Protocols:gDIV = ""
801        Variable catVSTableExists, num_sans_files
802        catVSTableExists = WinType("catVSTable")
803        //??BUG?? V_flag returns 1 even if no selection?
804        //check manually for null selection
805        //Print "local v_flag = ",num2str(V_flag)
806        Wave/T LocFilenames = $"root:myGlobals:CatVSHeaderInfo:Filenames"
807        if (catVSTableExists != 0)
808                GetSelection table,CatVSTable,7
809                if(strsearch(S_selection,"Filenames",0) == 0)
810                   //selection OK, add to list
811        Duplicate/O/R=[V_startRow,V_endRow] LocFilenames, filenames
812                Wave/T selectedFiles = $"filenames"
813           num_sans_files = numpnts(selectedFiles)           
814                   SVAR temp = root:myGlobals:Protocols:gDIV
815                        temp = selectedFiles[0]
816                Else
817                        DoAlert 0,"Invalid selection from the File Catalog table"
818                Endif
819        else
820                //no selection
821                DoAlert 0,"No file selected from File Catalog table or no File Catalog table available"
822        Endif
823       
824End
825
826//button control function to set the background (MSK) file name to the
827//selected name in the CAT/SHORT window
828//the version number of the file need not be selected, it will be added later if needed
829//there can only be one MSK file for a given protocol
830//
831Function PickMASKButton(ctrlName) : ButtonControl
832        String ctrlName
833       
834        //always reset the list of MASK files - ther can be only one
835        String/G root:myGlobals:Protocols:gMASK = ""
836       
837        Variable catVSTableExists, num_sans_files
838        catVSTableExists = WinType("catVSTable")
839        //??BUG?? V_flag returns 1 even if no selection?
840        //check manually for null selection
841        //Print "local v_flag = ",num2str(V_flag)
842        Wave/T LocFilenames = $"root:myGlobals:CatVSHeaderInfo:Filenames"
843        if (catVSTableExists != 0)
844                GetSelection table,CatVSTable,7
845                if(strsearch(S_selection,"Filenames",0) == 0)
846                        //selection OK, add to list
847                Duplicate/O/R=[V_startRow,V_endRow] LocFilenames, filenames
848                Wave/T selectedFiles = $"filenames"
849                num_sans_files = numpnts(selectedFiles)           
850                        SVAR temp = root:myGlobals:Protocols:gMASK
851                        temp = selectedFiles[0]
852        Else
853                        DoAlert 0,"Invalid selection from the File Catalog table"
854                Endif
855        else
856                //no selection
857                DoAlert 0,"No file selected from File Catalog table or no File Catalog table available"
858        Endif
859       
860End
861
862//button action function to reduce one file with the information specified on
863//the panel
864//a temporary protocol is created, even if the fields correspond to a named protocol
865//(only the protocol wave values are written to the data header, but the name is written to the
866//schematic - this could cause some unwanted confusion)
867//
868//if a sample file(s) is selected, only that file(s) will be reduced
869//if no file is selected, the user will be prompted with a standard open
870//dialog to select sample data file(s)
871//
872Function ReduceOneButton(ctrlName) : ButtonControl
873        String ctrlName
874
875        //parse the information on the panel and assign to tempProtocol wave (in protocol folder)
876        //and execute
877        String temp="root:myGlobals:Protocols:tempProtocol"
878        Wave/T w=$temp
879        Variable ii=0,num=8
880        do
881                w[ii] = ""
882                ii+=1
883        while(ii<num)
884       
885        MakeProtocolFromPanel(w)
886
887        //the "current" protocol is the "tempProtocol" that was parsed from the panel input
888        //set the global, so that the data writing routine can find the protocol wave (fatal otherwise)
889        String/G root:myGlobals:Protocols:gProtoStr="tempProtocol"
890       
891        PathInfo catPathName                    //this is where the files came from
892        String pathstr=S_path,samStr
893       
894        //take the string from the panel
895        SVAR tempStr = root:myGlobals:Protocols:gSAM
896       
897        if( (strlen(tempStr) == 0) || (cmpstr(tempStr,"ask")==0) )
898                //let user select the files
899                tempStr="ask"
900                ExecuteProtocol(temp,tempStr)
901                return(0)
902        Else
903                //parse the list of numbers
904                //send only the filenames, without paths
905                samStr = ParseRunNumberList(tempStr)
906                If(strlen(samStr)==0)
907                        DoAlert 0,"The SAM file number cound not be interpreted. Please enter a valid run number or filename"
908                        return(1)
909                endif
910                tempStr=samStr          //reset the global
911                ExecuteProtocol(temp,samStr)
912                return(0)
913        endif
914End
915
916
917//button action function will prompt user for absolute scaling parameters
918//either from an empty beam file or by manually entering the 4 required values
919//uses the same function and shared global string as the questionnare form of reduction
920//in "protocol.ipf" - the string is root:myGlobals:Protocols:gAbsStr
921//
922Function SetABSParamsButton(ctrlName) : ButtonControl
923        String ctrlName
924
925        //will prompt for a list of ABS parameters (4) through a global string variable
926       
927        Execute "AskForAbsoluteParams_Quest()"
928       
929End
930
931//simple button action procedure to bring the CAT/SHORT notebook window to the front
932//in case it's buried behind other windows
933//
934Function ShowCATButton(ctrlName) : ButtonControl
935        String ctrlName
936
937        DoWindow/F CatVSTable
938        if(V_flag==0)
939                DoAlert 0,"There is no File Catalog table window. Use the File Catalog table button to create one."
940        Endif
941       
942End
943
944//the panel recreation macro
945//
946Window ProtocolPanel()
947        PauseUpdate; Silent 1           // building window...
948        NewPanel /W=(553,48,851,500) /K=1 as "Data Reduction Protocol"
949        ModifyPanel cbRGB=(27589,43441,64159), fixedSize=1
950        SetDrawLayer UserBack
951        DrawLine 2,25,300,25
952        DrawLine 2,69,300,69
953        DrawLine 2,120,300,120
954        DrawLine 2,169,300,169
955        DrawLine 2,217,300,217
956        DrawLine 2,262,300,262
957        DrawLine 2,357,300,357
958        DrawLine 2,379,300,379
959        DrawLine 2,308,300,308
960        Button button0,pos={12,2},size={90,20},proc=DoCatShort,title="File Catalog"
961        Button button0,help={"Use this button to generate a catalog of raw data file headers. Select files from the list for EMP, BGD,..."}
962        Button button_help,pos={260,2},size={25,20},proc=ShowProtoHelp,title="?"
963        Button button_help,help={"Show the help file for setting up a reduction protocol"}
964        CheckBox prot_check,pos={5,75},size={74,14},title="Background"
965        CheckBox prot_check,help={"If checked, the specified background file will be included in the data reduction. If the file name is \"ask\", then the user will be prompted for the file"}
966        CheckBox prot_check,value= 1
967        Button pick_bgd,pos={114,75},size={100,20},proc=PickBGDButton,title="set BGD file"
968        Button pick_bgd,help={"This button will set the file selected in the File Catalog table to be the background file."}
969        Button recallProt,pos={7,406},size={107,20},proc=RecallProtocolButton,title="Recall Protocol"
970        Button recallProt,help={"Resets the panel to the file choices in  a previously saved protocol"}
971        Button del_protocol,pos={7,428},size={110,20},proc=DeleteProtocolButton,title="Delete Protocol"
972        Button del_protocol,help={"Use this to delete a previously saved protocol."}
973        Button done_protocol,pos={225,428},size={45,20},proc=DoneProtocolButton,title="Done"
974        Button done_protocol,help={"This button will close the panel. The panel can be recalled at any time from the SANS menu."}
975        Button saveProtocol,pos={7,384},size={100,20},proc=SaveProtocolButton,title="Save Protocol"
976        Button saveProtocol,help={"Saves the cerrent selections in the panel to a protocol which can be later recalled"}
977        CheckBox prot_check_1,pos={5,127},size={71,14},title="Empty Cell"
978        CheckBox prot_check_1,help={"If checked, the specified empty cell file will be included in the data reduction. If the file name is \"ask\", then the user will be prompted for the file"}
979        CheckBox prot_check_1,value= 1
980        CheckBox prot_check_2,pos={6,175},size={72,14},title="Sensitivity"
981        CheckBox prot_check_2,help={"If checked, the specified detector sensitivity file will be included in the data reduction. If the file name is \"ask\", then the user will be prompted for the file"}
982        CheckBox prot_check_2,value= 1
983        CheckBox prot_check_3,pos={9,268},size={43,14},title="Mask"
984        CheckBox prot_check_3,help={"If checked, the specified mask file will be included in the data reduction. If the file name is \"ask\", then the user will be prompted for the file"}
985        CheckBox prot_check_3,value= 1
986        Button pick_emp,pos={113,125},size={100,20},proc=PickEMPButton,title="set EMP file"
987        Button pick_emp,help={"This button will set the file selected in the File Catalog table to be the empty cell file."}
988        Button pick_DIV,pos={114,173},size={100,20},proc=PickDIVButton,title="set DIV file"
989        Button pick_DIV,help={"This button will set the file selected in the File Catalog table to be the sensitivity file."}
990        Button pick_MASK,pos={119,266},size={100,20},proc=PickMASKButton,title="set MASK file"
991        Button pick_MASK,help={"This button will set the file selected in the File Catalog table to be the mask file."}
992        SetVariable bgdStr,pos={7,98},size={250,15},title="file:"
993        SetVariable bgdStr,help={"Filename of the background file(s) to be used in the data reduction"}
994        SetVariable bgdStr,limits={-Inf,Inf,0},value= root:myGlobals:Protocols:gBGD
995        SetVariable empStr,pos={8,148},size={250,15},title="file:"
996        SetVariable empStr,help={"Filename of the empty cell file(s) to be used in the data reduction"}
997        SetVariable empStr,limits={-Inf,Inf,0},value= root:myGlobals:Protocols:gEMP
998        SetVariable divStr,pos={9,197},size={250,15},title="file:"
999        SetVariable divStr,help={"Filename of the detector sensitivity file to be used in the data reduction"}
1000        SetVariable divStr,limits={-Inf,Inf,0},value= root:myGlobals:Protocols:gDIV
1001        SetVariable maskStr,pos={9,289},size={250,15},title="file:"
1002        SetVariable maskStr,help={"Filename of the mask file to be used in the data reduction"}
1003        SetVariable maskStr,limits={-Inf,Inf,0},value= root:myGlobals:Protocols:gMASK
1004        Button ReduceOne,pos={194,384},size={100,20},proc=ReduceOneButton,title="Reduce A File"
1005        Button ReduceOne,help={"Using the panel selections, the specified sample file will be reduced. If none is specified, the user will be prompted for a sample file"}
1006        CheckBox prot_check_4,pos={5,30},size={53,14},title="Sample"
1007        CheckBox prot_check_4,help={"If checked, the specified sample file will be included in the data reduction. If the file name is \"ask\", then the user will be prompted for the file"}
1008        CheckBox prot_check_4,value= 1
1009        Button pick_sam,pos={115,28},size={100,20},proc=PickSAMButton,title="set SAM file"
1010        Button pick_sam,help={"This button will set the file selected in the File Catalog table to be the sample file"}
1011        SetVariable samStr,pos={6,50},size={250,15},title="file:"
1012        SetVariable samStr,help={"Filename of the sample file(s) to be used in the data reduction"}
1013        SetVariable samStr,limits={-Inf,Inf,0},value= root:myGlobals:Protocols:gSAM
1014        Button pick_ABS,pos={115,220},size={110,20},proc=SetABSParamsButton,title="set ABS params"
1015        Button pick_ABS,help={"This button will prompt the user for absolute scaling parameters"}
1016        CheckBox prot_check_9,pos={7,222},size={59,14},title="Absolute"
1017        CheckBox prot_check_9,help={"If checked, absolute calibration will be included in the data reduction. If the parameter list is \"ask\", then the user will be prompted for absolue parameters"}
1018        CheckBox prot_check_9,value= 1
1019        SetVariable absStr,pos={7,243},size={250,15},title="parameters:"
1020        SetVariable absStr,help={"Keyword-string of values necessary for absolute scaling of data. Remaining parameters are taken from the sample file."}
1021        SetVariable absStr,limits={-Inf,Inf,0},value= root:myGlobals:Protocols:gAbsStr
1022        Button show_cat,pos={120,2},size={120,20},proc=ShowCATButton,title="Show File Catalog"
1023        Button show_cat,help={"Brings the current condensed File Catalog table to the front"}
1024        CheckBox prot_check_5,pos={6,311},size={56,14},title="Average"
1025        CheckBox prot_check_5,help={"If checked, the specified averaging will be performed at the end of the data reduction."}
1026        CheckBox prot_check_5,value= 1
1027        Button pick_AVE,pos={108,313},size={150,20},proc=SetAverageParamsButtonProc,title="set AVERAGE params"
1028        Button pick_AVE,help={"Prompts the user for the type of 1-D averaging to perform, as well as saving options"}
1029        SetVariable aveStr,pos={9,336},size={250,15},title="parameters:"
1030        SetVariable aveStr,help={"Keyword-string of choices used for averaging and saving the 1-D data files"}
1031        SetVariable aveStr,limits={-Inf,Inf,0},value= root:myGlobals:Protocols:gAVE
1032        //only show DRK if user wants to see it
1033        //if global = 1,then show => set disable = 0
1034        CheckBox prot_check_6,pos={6,363},size={113,14},proc=DrkCheckProc,title="Use DRK correction"
1035        CheckBox prot_check_6,help={"If checked, the selected file will be used for DRK correction. Typically this is NOT checked"}
1036        CheckBox prot_check_6,value= 0,disable = (!root:myGlobals:gAllowDRK)
1037        SetVariable drkStr,pos={120,363},size={150,15},title="."
1038        SetVariable drkStr,help={"DRK detector count file"},disable = (!root:myGlobals:gAllowDRK)
1039        SetVariable drkStr,limits={-Inf,Inf,0},value= root:myGlobals:Protocols:gDRK
1040        Button export_button, size={60,20},pos={125,384},title="Export",proc=ExportProtocol
1041        Button export_button, help={"Exports the protocol to disk for Importing into another experiment"}
1042        Button import_button, size={60,20},pos={125,406},title="Import",proc=ImportProtocol
1043        Button import_button,help={"Imports a protocol from disk for use in this experiment"}
1044EndMacro
1045
1046//activated when user checks/unchecks the box
1047//either prompts for a file using a standard dialog, or removes the current file
1048Function DrkCheckProc(ctrlName,checked) : CheckBoxControl
1049        String ctrlName
1050        Variable checked                //Desired state, not previous state
1051
1052        SVAR drkStr=root:myGlobals:Protocols:gDRK
1053        if(checked==1)
1054                //print "Unchecked on call"
1055                //this just asks for the filename, doesn't open the file
1056                String msgStr="Select the DRK file",fullPath="",fileStr=""
1057                Variable refnum
1058               
1059                Open/D/R/T="????"/M=(msgStr)/P=catPathName refNum
1060                fullPath = S_FileName           //fname is the full path
1061                if(cmpstr(fullpath,"")==0)
1062                        //user cancelled
1063                        CheckBox prot_check_6,value=0           //keep box unchecked
1064                        return(0)
1065                Endif
1066                fileStr=GetFileNameFromPathNoSemi(fullPath)
1067                //Print fileStr
1068                //update the global string
1069                drkStr = ReplaceStringByKey("DRK",drkStr,fileStr,"=",",")
1070                drkStr = ReplaceNumberByKey("DRKMODE", drkStr, 10 ,"=",",")
1071        else
1072                //print "checked on call"
1073                drkStr="DRK=none,DRKMODE=0,"            //change the global
1074        endif
1075       
1076End
1077
1078
1079Function ShowProtoHelp(ctrlName) : ButtonControl
1080        String ctrlName
1081        DisplayHelpTopic/K=1 "SANS Data Reduction Tutorial[Build a Data Reduction Protocol]"
1082End
1083
1084//button action procedure to get the type of average requested by the user
1085//presented as a missing parameter dialog, which is really user-UN-friendly
1086//and will need to be re-thought. Defaults of dialog are set for normal
1087//circular average, so typically click "continue" and proceed
1088//
1089Function SetAverageParamsButtonProc(ctrlName) : ButtonControl
1090        String ctrlName
1091       
1092        Execute "GetAvgInfo()"
1093       
1094        //set the global string
1095        SVAR tempStr = root:myGlobals:Protocols:gAvgInfoStr
1096        String/G root:myGlobals:Protocols:gAVE = tempStr
1097
1098End
1099
1100//procedure called by protocol panel to ask user for agerage type choices
1101// somewhat confusing and complex, but maybe as good as it gets.
1102//
1103Proc GetAvgInfo(av_typ,autoSave,autoName,autoPlot,side,phi,dphi,width,QCtr,QDelta)
1104        String av_typ,autoSave,AutoName,autoPlot,side
1105        Variable phi=0,dphi=10,width=10,Qctr = 0.01,qDelta=10
1106        Prompt av_typ, "Type of Average",popup,"Circular;Sector;Rectangular;Annular;2D_ASCII;QxQy_ASCII;PNG_Graphic"
1107// comment out above line in DEMO_MODIFIED version, and uncomment the line below (to disable PNG save)
1108//      Prompt av_typ, "Type of Average",popup,"Circular;Sector;Rectangular;Annular;2D_ASCII;QxQy_ASCII"
1109        Prompt autoSave,"Save files to disk?",popup,"Yes;No"
1110        Prompt autoName,"Auto-Name files?",popup,"Auto;Manual"
1111        Prompt autoPlot,"Plot the averaged Data?",popup,"Yes;No"
1112        Prompt side,"Include detector halves?",popup,"both;right;left"
1113        Prompt phi,"Orientation Angle (-90,90) degrees (Rectangular or Sector)"
1114        Prompt dphi, "Azimuthal range (0,45) degrees (Sector only)"
1115        Prompt width, "Width of Rectangular average (1,128)"
1116        Prompt Qctr, "q-value of center of annulus"
1117        Prompt Qdelta,"Pixel width of annulus"
1118
1119        //assign results of dialog to key=value string, semicolon separated
1120        //do only what is necessary, based on av_typ
1121        String/G root:myGlobals:Protocols:gAvgInfoStr=""
1122       
1123        // all averages need these four values
1124        root:myGlobals:Protocols:gAvgInfoStr += "AVTYPE=" + av_typ + ";"
1125        root:myGlobals:Protocols:gAvgInfoStr += "SAVE=" + autoSave + ";"
1126        root:myGlobals:Protocols:gAvgInfoStr += "NAME=" + autoName + ";"
1127        root:myGlobals:Protocols:gAvgInfoStr += "PLOT=" + autoPlot + ";"
1128       
1129        if(cmpstr(av_typ,"Sector")==0)
1130                root:myGlobals:Protocols:gAvgInfoStr += "SIDE=" + side + ";"
1131                root:myGlobals:Protocols:gAvgInfoStr += "PHI=" + num2str(phi) + ";"
1132                root:myGlobals:Protocols:gAvgInfoStr += "DPHI=" + num2str(dphi) + ";"
1133        Endif
1134       
1135        if(cmpstr(av_typ,"Rectangular")==0)
1136                root:myGlobals:Protocols:gAvgInfoStr += "SIDE=" + side + ";"
1137                root:myGlobals:Protocols:gAvgInfoStr += "PHI=" + num2str(phi) + ";"
1138                root:myGlobals:Protocols:gAvgInfoStr += "WIDTH=" + num2str(width) + ";"
1139        Endif
1140       
1141        if(cmpstr(av_typ,"Annular")==0)
1142                root:myGlobals:Protocols:gAvgInfoStr += "QCENTER=" + num2str(QCtr) + ";"
1143                root:myGlobals:Protocols:gAvgInfoStr += "QDELTA=" + num2str(QDelta) + ";"
1144        Endif
1145End
1146
1147//not used????
1148//checks the syntax of all of the file fields in the panel
1149Function CheckProtocolSyntax(ctrlName) : ButtonControl
1150        String ctrlName
1151       
1152        String retStr=""
1153        //SAM
1154        SVAR list = root:myGlobals:Protocols:gSAM
1155        retStr = ParseRunNumberList(list)
1156        if(strlen(retStr)==0)
1157                //error
1158                Print "SAM Syntax Error"
1159                return(1)
1160        else
1161                list = retStr
1162                Print "SAM syntax OK"
1163        Endif
1164
1165        //MASK
1166        SVAR list = root:myGlobals:Protocols:gMASK
1167        retStr = ParseRunNumberList(list)
1168       
1169End
1170//*************
1171
1172
1173
1174//
1175// Procedure files for creating and executing a data reduction protocol
1176//
1177//**** ONLY invoked from the MAIN PANEL****
1178//Procedure for reducing a sample file (multiple added files) with a specified
1179//protocol. User may create a new protocol, and will be prompted
1180//for information "questionnare-style" where the user must know the
1181//filenames for empty cell, background...etc.. as they will be presented
1182//with standard file open dialogs to select each file desired for use in the
1183//new protocol
1184//once a protocol is selected (or created) the uer is propmted for sample data
1185// and the file is processed through the protocol.
1186//
1187Proc ReduceAFile()
1188
1189        String protocolName="",waveStr="",samStr = "ask"
1190        Variable err
1191       
1192        //pick a protocol wave from the Protocols folder
1193        //must switch to protocols folder to get wavelist (missing parameter)
1194        SetDataFolder root:myGlobals:Protocols
1195        PickAProtocol()
1196       
1197        //get the selected protocol wave choice through a global string variable
1198        protocolName = root:myGlobals:Protocols:gProtoStr
1199       
1200        //If "CreateNew" was selected, go to the questionnare, to make a new set
1201        //and put the name of the new Protocol wave in gProtoStr
1202        if(cmpstr("CreateNew",protocolName) == 0)
1203                ProtocolQuestionnare()
1204                protocolName = root:myGlobals:Protocols:gProtoStr
1205        Endif
1206       
1207        //give the full path:name to the executeProtocol function
1208        waveStr = "root:myGlobals:Protocols:"+protocolName
1209        //samStr is set at top to "ask", since this is the action always desired from "ReduceAFile"
1210       
1211        //////
1212        //PathInfo catPathName                  //this is where the files came from
1213        //String pathstr=S_path,samStr
1214        //samStr = BuildList(tempStr,pathStr)           //ExecuteProtocol() needs full path for SAM files
1215        /////
1216       
1217        ExecuteProtocol(waveStr,samStr)
1218       
1219        //return data folder to root before Macro is done
1220        SetDataFolder root:
1221       
1222End
1223
1224
1225//prompts the user to pick a previously created protocol from a popup list
1226//of given the option to create a new protocol
1227//the chosen protocol is passed back to the calling procedure by a global string
1228//the popup is presented as a missing parameter dialog (called with empty parameter list)
1229//
1230Proc PickAProtocol(protocol)
1231        String Protocol
1232        Prompt Protocol "Pick A Protocol",popup, WaveList("*",";","")
1233       
1234        String/G  root:myGlobals:Protocols:gProtoStr = protocol
1235End
1236
1237Proc DeleteAProtocol(protocol)
1238        String Protocol
1239//      Prompt Protocol "Delete A Protocol",popup, WaveList("*",";","")
1240        Prompt Protocol "Delete A Protocol",popup, DeletableProtocols()
1241
1242        String/G  root:myGlobals:Protocols:gProtoStr = protocol
1243End
1244
1245Function/S DeletableProtocols()
1246        String list=WaveList("*",";","")
1247
1248        list= RemoveFromList("Base", list  , ";")
1249        list= RemoveFromList("DoAll", list  , ";")
1250        list= RemoveFromList("CreateNew", list  , ";")
1251        list= RemoveFromList("tempProtocol", list  , ";")
1252        if(cmpstr(list,"")==0)
1253                list = "_no_protocols_;"
1254        endif
1255       
1256        return(list)
1257End
1258//missing paramater dialog to solicit user for a waveStr for the protocal
1259//about to be created
1260//name is passed back as a global string and calling procedure is responsible for
1261//checking for wave conflicts and valid names
1262//
1263Proc AskForName(protocol)
1264        String Protocol
1265        Prompt Protocol "Enter a new name for your protocol (no extension)"
1266       
1267        String/G  root:myGlobals:Protocols:gNewStr = protocol
1268End
1269
1270//this is a lengthy procedure for sequentially polling the user about what data
1271//reduction steps they want to be performed during the protocol
1272//ensures that a valid protocol name was chosen, then fills out each "item"
1273//(6 total) needed for reduction
1274//it the user cancels at nay point, the partial protocol will be deleted
1275//
1276Function ProtocolQuestionnare()
1277        String filename,cmd
1278        Variable notDone,refnum
1279       
1280        //prompt for name of new protocol wave to save
1281        do
1282                Execute "AskForName()"
1283                SVAR newProtoStr = root:myGlobals:Protocols:gNewStr
1284               
1285                //make sure it's a valid IGOR name
1286                newProtoStr = CleanupName(newProtoStr,0)        //strict naming convention
1287                String/G root:myGlobals:Protocols:gNewStr=newProtoStr           //reassign, if changed
1288                //Print "newProtoStr = ",newProtoStr
1289               
1290                SetDataFolder root:myGlobals:Protocols
1291                if(WaveExists( $("root:myGlobals:Protocols:" + newProtoStr) ) == 1)
1292                        //wave already exists
1293                        DoAlert 0,"that name is already in use. Please pick a new name"
1294                        notDone = 1
1295                else
1296                        //name is  good
1297                        notDone = 0
1298                Endif
1299        while(notDone)
1300       
1301        //Print "protocol questionnare is "+newProtocol
1302       
1303        //make a new text wave (6 points) and fill it in, in response to questions
1304        SetDataFolder root:myGlobals:Protocols //(redundant - full wave specs are used)
1305        Make/O/T/N=8 $("root:myGlobals:Protocols:" + newProtoStr)
1306        Wave/T newProtocol = $("root:myGlobals:Protocols:" + newProtoStr)
1307       
1308        //ask the questions
1309        /////
1310        //*****Multiple files in these lists are full paths/filenames which may or may not
1311        //have semicolon version numbers in the filename. Therefore, construct the list with
1312        //COMMAS as separators - to avoid messy parsing
1313        ///////
1314       
1315       
1316//////////////////////////
1317        String drkStr="",fileStr=""
1318        DoAlert 1,"Do you want to correct your data for DRK (beam off) counts?"
1319        if(V_flag == 1)         //1=yes
1320                //prompt for DRK  file, but don't actually open it (/D flag)
1321                Open/D/R/T="TEXT????"/M="Select the DRK file"/P=catPathName refnum
1322                //check for cancel
1323                if(strlen(S_filename)==0)
1324                        //user cancelled, abort
1325                        KillWaves/Z newProtocol
1326                        SetDataFolder root:
1327                        Abort "Incomplete protocol has been deleted"
1328                Endif
1329                //assign filename (just the name) to [6]
1330                fileStr = GetFileNameFromPathNoSemi(S_filename)
1331                drkStr = "DRK=none,DRKMODE=0,"
1332                drkStr = ReplaceStringByKey("DRK",drkStr,fileStr,"=",",")
1333                drkStr = ReplaceNumberByKey("DRKMODE", drkStr, 10 ,"=",",")     
1334                newProtocol[6] = drkStr
1335        else
1336                //no Work.DRK desired
1337                newProtocol[6] = "DRK=none,DRKMODE=0,"
1338        Endif
1339       
1340////////////
1341       
1342/////////////////
1343        DoAlert 1,"Do you want to subtract background from your data?"
1344        if(V_flag == 1)         //1=yes
1345                //prompt for background file, but don't actually open it (/D flag)
1346                Open/D/R/T="TEXT????"/M="Select the Background data file"/P=catPathName refnum
1347                //check for cancel
1348                if(strlen(S_filename)==0)
1349                        //user cancelled, abort
1350                        KillWaves/Z newProtocol
1351                        SetDataFolder root:
1352                        Abort "Incomplete protocol has been deleted"
1353                Endif
1354                //assign filename (full path) to [0]
1355                newProtocol[0] = GetFileNameFromPathNoSemi(S_filename)
1356               
1357                notDone=1
1358                do
1359                        //prompt for additional background files
1360                        DoAlert 1,"Do you want to add another background file?"
1361                        if(V_flag == 1)         //yes
1362                                Open/D/R/T="TEXT????"/M="Select another Background data file"/P=catPathName refnum
1363                                //check for cancel
1364                                if(strlen(S_filename)==0)
1365                                        //user cancelled, abort ********maybe just break out of the loop here
1366                                        KillWaves/Z newProtocol
1367                                        SetDataFolder root:
1368                                        Abort "Incomplete protocol has been deleted"
1369                                Endif
1370                                //assign filename (full path) to [0]
1371                                newProtocol[0] += "," + GetFileNameFromPathNoSemi(S_filename)           //***COMMA separated list
1372                                notDone = 1             //keep going
1373                        else
1374                                notDone = 0                     //no more to add
1375                        Endif
1376                While(notDone)
1377        else            //no background desired
1378                newProtocol[0] = "none"
1379        Endif
1380////////////////////// 
1381        DoAlert 1,"Do you want to subtract empty cell scattering from your data?"
1382        if(V_flag == 1)         //1=yes
1383                //prompt for Empty cell file, but don't actually open it (/D flag)
1384                Open/D/R/T="TEXT????"/M="Select the Empty Cell data file"/P=catPathName refnum
1385                //check for cancel
1386                if(strlen(S_filename)==0)
1387                        //user cancelled, abort
1388                        KillWaves/Z newProtocol
1389                        SetDataFolder root:
1390                        Abort "Incomplete protocol has been deleted"
1391                Endif
1392                //assign filename (full path) to [1]
1393                newProtocol[1] = GetFileNameFromPathNoSemi(S_filename)
1394               
1395                notDone=1
1396                do
1397                        //prompt for additional Empty Cell files
1398                        DoAlert 1,"Do you want to add another Empty Cell file?"
1399                        if(V_flag == 1)         //yes
1400                                Open/D/R/T="TEXT????"/M="Select another Empty Cell data file"/P=catPathName refnum
1401                                //check for cancel
1402                                if(strlen(S_filename)==0)
1403                                        //user cancelled, abort ********maybe just break out of the loop here
1404                                        KillWaves/Z newProtocol
1405                                        SetDataFolder root:
1406                                        Abort "Incomplete protocol has been deleted"
1407                                Endif
1408                                //assign filename (full path) to [1]
1409                                newProtocol[1] += "," + GetFileNameFromPathNoSemi(S_filename)           //***COMMA separated list
1410                                notDone = 1             //keep going
1411                        else
1412                                notDone = 0                     //no more to add
1413                        Endif
1414                While(notDone)
1415        else            //no background desired
1416                newProtocol[1] = "none"
1417        Endif
1418//////////////////////////
1419        DoAlert 1,"Do you want to correct your data for detector sensitivity?"
1420        if(V_flag == 1)         //1=yes
1421                //prompt for DIV  file, but don't actually open it (/D flag)
1422                Open/D/R/T="TEXT????"/M="Select the detector sensitivity file"/P=catPathName refnum
1423                //check for cancel
1424                if(strlen(S_filename)==0)
1425                        //user cancelled, abort
1426                        KillWaves/Z newProtocol
1427                        SetDataFolder root:
1428                        Abort "Incomplete protocol has been deleted"
1429                Endif
1430                //assign filename (full path) to [2]
1431                newProtocol[2] = GetFileNameFromPathNoSemi(S_filename)
1432        else
1433                //no Work.DIV desired
1434                newProtocol[2] = "none"
1435        Endif   
1436//////////////////////////
1437        DoAlert 1,"Do you want to mask your files before averaging?"
1438        if(V_flag == 1)         //1=yes
1439                //prompt for mask  file, but don't actually open it (/D flag)
1440                Open/D/R/T="TEXT????MASK"/M="Select the mask file"/P=catPathName refnum
1441                //check for cancel
1442                if(strlen(S_filename)==0)
1443                        //user cancelled, abort
1444                        KillWaves/Z newProtocol
1445                        SetDataFolder root:
1446                        Abort "Incomplete protocol has been deleted"
1447                Endif
1448                //assign filename (full path) to [3]
1449                newProtocol[3] = GetFileNameFromPathNoSemi(S_filename)
1450        else
1451                //no MASK desired
1452                newProtocol[3] = "none"
1453        Endif   
1454       
1455        //absolute scaling
1456       
1457        //////////////////////////
1458        //ABS parameters stored as keyword=value string
1459        DoAlert 1,"Do you want absolute scaling?"
1460        if(V_flag == 1)         //1=yes
1461                //missing param - prompt for values, put in semicolon-separated list
1462                Execute "AskForAbsoluteParams_Quest()"
1463                SVAR absStr =  root:myGlobals:Protocols:gAbsStr
1464                newProtocol[4] = absStr
1465        else
1466                //no absolute scaling desired
1467                newProtocol[4] = "none"
1468        Endif   
1469       
1470        //type of average, plot?, auto/manual naming/saving... put in semicolon separated string
1471        //of KEY=<value> format for easy parsing
1472        //Kewords are: AVTYPE,PHI,DPHI,PLOT,SAVE,NAME,SIDE,WIDTH
1473        //note that AVTYPE,NAME,SIDE have string values, others have numerical values
1474        ///////////////////////
1475        DoAlert 1,"Do you want to average your data to I vs. q?"
1476        if(V_flag == 1)         //1=yes
1477                String/G root:myGlobals:Protocols:gAvgInfoStr = ""
1478                Execute "GetAvgInfo()"          //will put up missing paramter dialog and do all the work
1479                //:gAvgInfo is reset by the Proc(), copy this string tot he protocol
1480                SVAR tempStr=root:myGlobals:Protocols:gAvgInfoStr
1481               
1482                //get a file path for saving files, if desired
1483                /////no - save files to the same data folder as the one with the raw data
1484                //then only one path to manage.
1485                //String yesNo = StringByKey("SAVE", tempStr,"=", ";")
1486                //if(cmpstr("Yes",yesNo) == 0)          //0=yes
1487                        //NewPath/C/M="Select Folder"/O Save_path               //Save_path is the symbolic path
1488                //Endif
1489
1490                newProtocol[5] = tempStr
1491                KillStrings/Z tempStr
1492        else
1493                //no averaging desired
1494                newProtocol[5] = "AVTYPE=none"
1495        Endif
1496       
1497        //returns the name of the newly created (= currently in use) protocol wave through a global
1498        String/G root:myGlobals:Protocols:gProtoStr = newProtoStr
1499End
1500
1501//function to check the work files (to see what's already there)
1502//and compare that with the files that are supposed to be there, according to the
1503//current protocol (to save unnecessary time re-loading files)
1504//
1505//the "type" folder is checked for all files in the list req(ested)Files
1506//note that the list of files is a full path:name;ver, while the
1507//fileList in the folder is just the name (or a list of names)
1508//
1509//returns 0 false, if files are NOT present
1510//or 1 = true, yes, the files are there as requested
1511//
1512Function AreFilesThere(type,reqFiles)
1513        String type,reqFiles
1514       
1515        //in general, reqFiles is a list of full paths to files - which MAY include semicolon version numbers
1516        //reqFiles MUST be constructed with COMMAS as list separators, to avoid disaster
1517        //when the version numbers are interpreted as filenames
1518       
1519        //get the number of files requested
1520        Variable nReq,nCur,match,ii
1521        nReq = ItemsInList(reqFiles,",")
1522       
1523        //get the name of the file currently in BGD - in the global fileList
1524        //fileList has NAMES ONLY - since it was derived from the file header
1525        String testStr
1526        testStr = "root:"+type+":fileList"
1527        if(Exists(testStr) == 2)                //2 if string variable exists
1528                SVAR curFiles = $testStr
1529        else
1530                //no files currently in type folder, return zero
1531                Return (0)
1532        Endif
1533        //get the number of files already in folder
1534        nCur = ItemsInList(curFiles,";")
1535        If(nCur != nReq)
1536                Return (0)              //quit now, the wrong number of files present
1537        Endif
1538        //right number of files... are the names right...
1539        //check for a match (case-sensitive!!) of each requested file in the curFile string
1540        //need to extract filenames from reqFiles, since they're the full path and name
1541       
1542        ii=0
1543        do
1544                testStr = StringFromList(ii,reqFiles,",")       //testStr is the Nth full path and filename
1545                //testStr = GetFileNameFromPathNoSemi(testStr)  //testStr will now be just the filename
1546                match = stringmatch(curFiles,testStr)
1547                If(!match)
1548                        Return (0)              //req file was not found in curFile list - get out now
1549                Endif
1550                ii+=1
1551        while(ii<nreq)
1552       
1553        Return (1)              //indicate that files are OK, no changes needed
1554End
1555
1556//will add the files specified in the protocol to the "type" folder
1557//will add multiple files together if more than one file is requested
1558//(list is a comma delimited list of filenames, with NO path information)
1559//
1560// This routine NOW DOES check for the possibility that the filenames may have ";vers" from the
1561// VAX - data should be picked up from Charlotte, where it won't have version numbers.
1562//
1563Function AddFilesInList(type,list)
1564        String type,list
1565       
1566        //type is the work folder to put the data into, and list is a COMMA delimited list of paths/names
1567        Variable num,ii,err=0,refNum
1568        String filename,pathStr=""
1569        PathInfo catPathName                    //this is where the files are
1570        pathstr=S_path
1571       
1572        num = ItemsInList(list,",")             // comma delimited list
1573       
1574        ii=0
1575        do
1576                //FindValidFilename only needed in case of vax version numbers
1577                filename = pathStr + FindValidFilename(StringFromList(ii,list,","))
1578                Open/Z/R refnum as filename
1579                if(V_flag != 0)         //file not found
1580                        //Print "file not found AddFilesInList()"
1581                        //Print filename
1582                        err = 1
1583                        return(err)
1584                Endif
1585                Close refnum            //file was found and opened, so close it
1586                ReadHeaderAndData(filename)
1587                if(ii == 0)
1588                        //first pass, wipe out the old contents of the work file
1589                        err =  Raw_to_work(type)
1590                else
1591                        err = Add_raw_to_work(type)
1592                Endif
1593                ii+=1
1594        while(ii<num)
1595        return(err)
1596End
1597
1598//function will reduce a sample file (or ask for file(s))
1599//using the protocol named as "protoStr" in the Protocols subfolder
1600//samStr is the file(s) or "ask" to force prompt
1601//sequentially proceeds through flowchart, doing reduction steps as needed
1602//show Schematic to debug what steps/values were used
1603//
1604//function is long, but straightforward logic
1605//
1606Function ExecuteProtocol(protStr,samStr)
1607        String protStr,samStr
1608        //protStr is the full path to the selected protocol wave
1609        //samStr is either "ask" or the name ONLY ofthe desired sample data file(s) (NO PATH)
1610        WAVE/T prot = $protStr
1611        SetDataFolder root:myGlobals:Protocols
1612       
1613        Variable filesOK,err,notDone
1614        String activeType, msgStr, junkStr, pathStr=""
1615        PathInfo catPathName                    //this is where the files are
1616        pathStr=S_path
1617       
1618       
1619        //Parse the instructions in the prot wave
1620        //0 - bkg
1621        //1 - emp
1622        //2 - div
1623        //3 - mask
1624        //4 - abs params c2-c5
1625        //5 - average params
1626        //6 = DRK file (**out of sequence)
1627       
1628        //prompt for sam data => read raw data, add to sam folder
1629        //or parse file(s) from the input paramter string
1630        activeType = "SAM"
1631        msgStr = "Select sample data"
1632        //Ask for SAM file or parse
1633        do
1634                if((cmpstr(samStr,"ask") == 0) || (cmpstr(samStr,"")==0) )              //zero if strings are equal
1635                        err = ReadBinarySANS(msgStr)            //will prompt for file
1636                        if(err)
1637                                PathInfo/S catPathName
1638                                Abort "reduction sequence aborted"
1639                        endif
1640                        err =  Raw_to_work(activeType)          //this is the first file (default)
1641                        //Ask for another SAM file
1642                        do
1643                                DoAlert 1,"Do you want to add another Sample file?"
1644                                if(V_flag == 1)         //yes
1645                                        err = ReadBinarySANS(msgStr)            //will prompt for file
1646                                        if(err)
1647                                                PathInfo/S catPathName
1648                                                Abort "reduction sequence aborted"
1649                                        endif
1650                                        err = Add_raw_to_work(activeType)
1651                                        notDone = 1
1652                                else
1653                                        notDone = 0
1654                                endif
1655                        while(notDone)
1656                        break
1657                Endif
1658                //"none" is not an option - you always need a sample file - "none" will never return zero
1659                //if not "ask" AND not "none" then try to parse the filenames
1660                If((cmpstr(samStr,"none") != 0) && (cmpstr(samStr,"ask") != 0))
1661                        filesOK = AreFilesThere(activeType,samStr)              //return 1 if correct files are already there
1662                        if(!filesOK)
1663                                //add the correct file(s) to SAM
1664                                err = AddFilesInList(activeType,samStr)
1665                                if(err)
1666                                        //Print "samstr = ",samStr
1667                                        Abort "SAM file not found, reset SAM file"
1668                                Endif
1669                        Endif
1670                Endif
1671        While(0)
1672        //always update
1673        UpdateDisplayInformation(ActiveType)
1674       
1675        //check for bkg file  -- "ask" might not fail - "ask?" will - ? not allowed in VAX filenames
1676        // add if needed
1677        //use a "case" statement
1678        msgStr = "Select background file"
1679        activeType = "BGD"
1680        do
1681                if(cmpstr(prot[0],"ask") == 0)          //zero if strings are equal
1682                        err = ReadBinarySANS(msgStr)            //will prompt for file
1683                        if(err)
1684                                PathInfo/S catPathName
1685                                Abort "reduction sequence aborted"
1686                        endif
1687                        err =  Raw_to_work(activeType)          //this is the first file (default)
1688                        //Ask for another BGD file
1689                        do
1690                                DoAlert 1,"Do you want to add another Background file?"
1691                                if(V_flag == 1)         //yes
1692                                        err = ReadBinarySANS(msgStr)            //will prompt for file
1693                                        if(err)
1694                                                PathInfo/S catPathName
1695                                                Abort "reduction sequence aborted"
1696                                        endif
1697                                        err = Add_raw_to_work(activeType)
1698                                        notDone = 1
1699                                else
1700                                        notDone = 0
1701                                endif
1702                        while(notDone)
1703                        UpdateDisplayInformation(ActiveType)            //update before breaking from loop
1704                        break
1705                Endif
1706                If(cmpstr(prot[0],"none") == 0)
1707                        //clean out the BKG folder?
1708                        //KillDataFolder root:BKG
1709                        //NewDataFolder/O root:BKG
1710                        break
1711                Endif
1712                //if not "ask" AND not "none" then try to parse the filenames
1713                If((cmpstr(prot[0],"none") != 0) && (cmpstr(prot[0],"ask") != 0))
1714                        filesOK = AreFilesThere(activeType,prot[0])
1715                        if(!filesOK)
1716                                //add the correct file(s) to BGD
1717                                err = AddFilesInList(activeType,prot[0])
1718                                If(err)
1719                                        Abort "BGD file not found. Reset BGD file list"
1720                                Endif
1721                        Endif
1722                        UpdateDisplayInformation(ActiveType)            //update before breaking from loop
1723                Endif
1724        While(0)
1725       
1726       
1727        //check for emp file (prot[1])
1728        // add if needed
1729        msgStr = "Select empty cell data"
1730        activeType = "EMP"
1731        do
1732                if(cmpstr(prot[1],"ask") == 0)
1733                        err = ReadBinarySANS(msgStr)            //will prompt for file
1734                        if(err)
1735                                PathInfo/S catPathName
1736                                Abort "reduction sequence aborted"
1737                        endif
1738                        err =  Raw_to_work(activeType)          //this is the first file (default)
1739                        //Ask for another EMP file
1740                        do
1741                                DoAlert 1,"Do you want to add another Empty Cell file?"
1742                                if(V_flag == 1)         //yes
1743                                        err = ReadBinarySANS(msgStr)            //will prompt for file
1744                                        if(err)
1745                                                PathInfo/S catPathName
1746                                                Abort "reduction sequence aborted"
1747                                        endif
1748                                        err = Add_raw_to_work(activeType)
1749                                        notDone = 1
1750                                else
1751                                        notDone = 0
1752                                endif
1753                        while(notDone)
1754                        UpdateDisplayInformation(ActiveType)            //update before breaking from loop
1755                        break
1756                Endif
1757                If(cmpstr(prot[1],"none") == 0)
1758                        //clean out the EMP folder?
1759                        //KillDataFolder root:EMP
1760                        //NewDataFolder/O root:EMP
1761                        break
1762                Endif
1763                //if not "ask" AND not "none" then try to parse the filenames
1764                If((cmpstr(prot[1],"none") != 0) && (cmpstr(prot[1],"ask") != 0))
1765                        filesOK = AreFilesThere(activeType,prot[1])
1766                        if(!filesOK)
1767                                //add the correct file(s) to BGD
1768                                err = AddFilesInList(activeType,prot[1])
1769                                If(err)
1770                                        Abort "EMP file not found. Reset EMP file list"
1771                                Endif
1772                        Endif
1773                        UpdateDisplayInformation(ActiveType)            //update before breaking from loop
1774                Endif
1775        While(0)
1776       
1777        //do the CORRECT step based on the answers to emp and bkg subtraction
1778        //by setting the proper"mode"
1779        //1 = both emp and bgd subtraction
1780        //2 = only bgd subtraction
1781        //3 = only emp subtraction
1782        //4 = no subtraction
1783        //additional modes 091301
1784        //11 = emp, bgd, drk
1785        //12 = bgd and drk
1786        //13 = emp and drk
1787        //14 = no subtractions
1788        //work.drk is from proto[6]
1789        //
1790        //subtracting just the DRK data is NOT an option - it doesnt' really make any physical sense
1791        // - in this case, DRK is skipped (equivalent to mode==4)
1792        // automatically accounts for attenuators given the lookup tables and the
1793        //desired subtractions
1794        //Attenuator lookup tables are alredy implemented (NG1 = NG7)
1795        //
1796       
1797        //read in the DRK data if necessary
1798        //only one file, assumed to be RAW data
1799        //
1800        String fname="",drkStr=""
1801        drkStr=StringByKey("DRK",prot[6],"=",",")
1802        if(cmpstr(drkStr,"none") != 0)
1803                err = ReadHeaderAndData( (pathStr+drkStr) )
1804                if(err)
1805                        PathInfo/S catPathName
1806                        Abort "reduction sequence aborted"
1807                endif
1808                err = Raw_to_Work_NoNorm("DRK")
1809        endif
1810       
1811        //dispatch to the proper "mode" of Correct()
1812        Variable mode=4,val
1813        do
1814                if( (cmpstr("none",prot[0]) == 0)       && (cmpstr("none",prot[1]) == 0) )
1815                        //no subtraction (mode = 4),
1816                        mode = 4
1817                Endif
1818                If((cmpstr(prot[0],"none") != 0) && (cmpstr(prot[1],"none") == 0))
1819                        //subtract BGD only
1820                        mode=2
1821                Endif
1822                If((cmpstr(prot[0],"none") == 0) && (cmpstr(prot[1],"none") != 0))
1823                        //subtract EMP only
1824                        mode=3
1825                Endif
1826                If((cmpstr(prot[0],"none") != 0) && (cmpstr(prot[1],"none") != 0))
1827                        // bkg and emp subtraction are to be done (BOTH not "none")
1828                        mode=1
1829                Endif
1830                activeType = "COR"
1831                //add in DRK mode (0= no used, 10 = used)
1832                val = NumberByKey("DRKMODE",prot[6],"=","," )
1833                mode += val
1834//              print "mode = ",mode
1835                err = Correct(mode)
1836                if(err)
1837                        SetDataFolder root:
1838                        Abort "error in Correct, called from executeprotocol, normal cor"
1839                endif
1840                UpdateDisplayInformation(ActiveType)            //update before breaking from loop
1841        While(0)
1842       
1843        //check for work.div file (prot[2])
1844        //add if needed
1845        // can't properly check the filename - so for now add and divide, if anything other than "none"
1846        //do/skip divide step based on div answer
1847        If(cmpstr("none",prot[2])!=0)           // if !0, then there's a file requested
1848                If(cmpstr("ask",prot[2]) == 0)
1849                        //ask user for file
1850                         junkStr = PromptForPath("Select the detector sensitivity file")
1851                        If(strlen(junkStr)==0)
1852                                SetDataFolder root:
1853                                Abort "No file selected, data reduction aborted"
1854                        Endif
1855                         ReadHeaderAndWork("DIV", junkStr)
1856                else
1857                        //assume it's a path, and that the first (and only) item is the path:file
1858                        //list processing is necessary to remove any final comma
1859                        junkStr = pathStr + StringFromList(0, prot[2],"," )
1860                        ReadHeaderAndWork("DIV",junkStr)
1861                Endif
1862                //got a DIV file, select the proper type of work data to DIV (= activeType)
1863                err = Divide_work(activeType)           //returns err = 1 if data doesn't exist in specified folders
1864                If(err)
1865                        SetDataFolder root:
1866                        Abort "data missing in DIV step, call from executeProtocol"
1867                Endif
1868                activeType = "CAL"
1869                UpdateDisplayInformation(ActiveType)            //update before breaking from loop
1870        Endif
1871       
1872        Variable c2,c3,c4,c5
1873        //do absolute scaling if desired
1874        if(cmpstr("none",prot[4])!=0)
1875                if(cmpstr("ask",prot[4])==0)
1876                        //get the params from the user
1877                        Execute "AskForAbsoluteParams_Quest()"
1878                        //then from the list
1879                        SVAR junkAbsStr = root:myGlobals:Protocols:gAbsStr
1880                        c2 = NumberByKey("TSTAND", junkAbsStr, "=", ";")        //parse the list of values
1881                        c3 = NumberByKey("DSTAND", junkAbsStr, "=", ";")
1882                        c4 = NumberByKey("IZERO", junkAbsStr, "=", ";")
1883                        c5 = NumberByKey("XSECT", junkAbsStr, "=", ";")
1884                else
1885                        //get the parames from the list
1886                        c2 = NumberByKey("TSTAND", prot[4], "=", ";")   //parse the list of values
1887                        c3 = NumberByKey("DSTAND", prot[4], "=", ";")
1888                        c4 = NumberByKey("IZERO", prot[4], "=", ";")
1889                        c5 = NumberByKey("XSECT", prot[4], "=", ";")
1890                Endif
1891                //get the sample trans and thickness from the activeType folder
1892                String destStr = "root:"+activeType+":realsread"
1893                Wave dest = $destStr
1894                Variable c0 = dest[4]           //sample transmission
1895                Variable c1 = dest[5]           //sample thickness
1896               
1897                err = Absolute_Scale(activeType,c0,c1,c2,c3,c4,c5)
1898                if(err)
1899                        SetDataFolder root:
1900                        Abort "Error in Absolute_Scale(), called from executeProtocol"
1901                endif
1902                activeType = "ABS"
1903                UpdateDisplayInformation(ActiveType)            //update before breaking from loop
1904        Endif
1905       
1906        //check for mask
1907        //add mask if needed
1908        // can't properly check the filename - so for now always add
1909        //doesn't change the activeType
1910        if(cmpstr("none",prot[3])!=0)
1911                If(cmpstr("ask",prot[3])==0)
1912                        //get file from user
1913                        junkStr = PromptForPath("Select Mask file")
1914                        If(strlen(junkStr)==0)
1915                                //no selection of mask file is not a fatal error, keep going, and let cirave()
1916                                //make a "null" mask
1917                                //if none desired, make sure that the old mask is deleted
1918                                //junkStr = GetDataFolder(1)
1919                                //SetDataFolder root:MSK
1920                                KillWaves/Z root:MSK:data
1921                                //SetDataFolder junkStr
1922                                DoAlert 0,"No Mask file selected, data not masked"
1923                        else
1924                                //read in the file from the dialog
1925                                ReadMCID_MASK(junkStr)
1926                        Endif
1927                else
1928                        //just read it in from the protocol
1929                        //list processing is necessary to remove any final comma
1930                        junkStr = pathStr + StringFromList(0, prot[3],"," )
1931                        ReadMCID_MASK(junkStr)
1932                Endif
1933        else
1934                //if none desired, make sure that the old mask is deleted
1935                //junkStr = GetDataFolder(1)
1936                //SetDataFolder root:MSK
1937                KillWaves/Z root:MSK:data
1938                //SetDataFolder junkStr
1939        Endif
1940       
1941        //mask data if desired (this is done automatically  in the average step) and is
1942        //not done explicitly here (if no mask in MSK folder, a null mask is created and "used")
1943       
1944        // average/save data as specified
1945       
1946        //Parse the keyword=<Value> string as needed, based on AVTYPE
1947       
1948        //average/plot first
1949        String av_type = StringByKey("AVTYPE",prot[5],"=",";")
1950        If(cmpstr(av_type,"none") != 0)
1951                If (cmpstr(av_type,"")==0)              //if the key could not be found... (if "ask" the string)
1952                        //get the averaging parameters from the user, as if the set button was hit
1953                        //in the panel
1954                        SetAverageParamsButtonProc("dummy")             //from "ProtocolAsPanel"
1955                        SVAR tempAveStr = root:myGlobals:Protocols:gAvgInfoStr
1956                        av_type = StringByKey("AVTYPE",tempAveStr,"=",";")
1957                else
1958                        //there is info in the string, use the protocol
1959                        //set the global keyword-string to prot[5]
1960                        String/G root:myGlobals:Protocols:gAvgInfoStr = prot[5]
1961                Endif
1962        Endif
1963       
1964        //convert the folder to linear scale before averaging, then revert by calling the window hook
1965        ConvertFolderToLinearScale(activeType)
1966       
1967        strswitch(av_type)      //dispatch to the proper routine to average to 1D data
1968                case "none":           
1969                        //still do nothing
1970                        break                   
1971                case "2D_ASCII":       
1972                        //do nothing
1973                        break
1974                case "QxQy_ASCII":
1975                        //do nothing
1976                        break
1977                case "PNG_Graphic":
1978                        //do nothing
1979                        break
1980                case "Rectangular":
1981                        RectangularAverageTo1D(activeType)
1982                        break
1983                case "Annular":
1984                        AnnularAverageTo1D(activeType)
1985                        break
1986                case "Circular":
1987                        CircularAverageTo1D(activeType)
1988                        break
1989                case "Sector":
1990                        CircularAverageTo1D(activeType)
1991                        break
1992                default:       
1993                        //do nothing
1994        endswitch
1995///// end of averaging dispatch
1996        // put data back on log or lin scale as set by default
1997        fRawWindowHook()
1998       
1999        //save data if desired
2000        String fullpath = "", newfileName=""
2001        String item = StringByKey("SAVE",prot[5],"=",";")               //does user want to save data?
2002        If( (cmpstr(item,"Yes")==0) && (cmpstr(av_type,"none") != 0) )         
2003                //then save
2004                //get name from textwave of the activeType dataset
2005                String textStr = "root:"+activeType+":textread"
2006                Wave/T textPath = $textStr
2007                If(WaveExists(textPath) == 1)
2008                        newFileName = GetNameFromHeader(textPath[0])
2009                else
2010                        newFileName = ""                        //if the header is missing?
2011                        //Print "can't read the header - newfilename is null"
2012                Endif
2013               
2014                //pick ABS or AVE extension
2015                String exten = activeType
2016                if(cmpstr(exten,"ABS") != 0)
2017                        exten = "AVE"
2018                endif
2019                if(cmpstr(av_type,"2D_ASCII") == 0)
2020                        exten = "ASC"
2021                endif
2022                if(cmpstr(av_type,"QxQy_ASCII") == 0)
2023                        exten = "DAT"
2024                endif
2025               
2026                //Path is catPathName, symbolic path
2027                //if this doesn't exist, a dialog will be presented by setting dialog = 1
2028                Variable dialog = 0
2029                PathInfo/S catPathName
2030                item = StringByKey("NAME",prot[5],"=",";")              //Auto or Manual naming
2031                If((cmpstr(item,"Manual")==0) || (cmpstr(newFileName,"") == 0))
2032                        //manual name if requested or if no name can be derived from header
2033                        fullPath = newfileName + "."+ exten //puts possible new name or null string in dialog
2034                        dialog = 1              //force dialog for user to enter name
2035                else
2036                        //auto-generate name and prepend path - won't put up any dialogs since it has all it needs
2037                        fullPath = S_Path + newFileName+ "." + exten   
2038                Endif
2039                //
2040                strswitch(av_type)     
2041                        case "Annular":
2042                                WritePhiave_W_Protocol(activeType,fullPath,dialog)
2043                                break
2044                        case "2D_ASCII":
2045                                Fast2DExport(activeType,fullPath,dialog)
2046                                break
2047                        case "QxQy_ASCII":
2048                                QxQy_Export(activeType,fullPath,dialog)
2049                                break
2050                        case "PNG_Graphic":
2051                                SaveAsPNG(activeType,fullpath,dialog)
2052                                break
2053                        default:
2054                                WriteWaves_W_Protocol(activeType,fullpath,dialog)
2055                endswitch
2056               
2057                //Print "data written to:  "+ fullpath
2058        Endif
2059       
2060        //done with everything in protocol list
2061        Return(0)
2062End
2063
2064//updates the currently displayed information to the data in "type"
2065//data folder - changes the title of the window and the global of the
2066//currently displayed data type - the recreation macro does the work
2067//
2068Function UpdateDisplayInformation(type)
2069        String type
2070
2071        String newTitle = "WORK_"+type
2072        DoWindow/F SANS_Data
2073        DoWindow/T SANS_Data, newTitle
2074        KillStrings/Z newTitle
2075       
2076        //need to update the display with "data" from the correct dataFolder
2077        //reset the current displaytype to "type"
2078        String/G root:myGlobals:gDataDisplayType=Type
2079       
2080        fRawWindowHook()
2081       
2082        //no error
2083        Return(0)
2084End
2085
2086//missing parameter dialog to solicit the 4 absolute intensity parameters
2087//from the user
2088//values are passed back as a global string variable (keyword=value)
2089//
2090Proc AskForAbsoluteParams(c2,c3,c4,c5)
2091        Variable c2=0.95,c3=0.1,c4=1,c5=32.0
2092        Prompt c2, "Standard Transmission"
2093        Prompt c3, "Standard Thickness (cm)"
2094        Prompt c4, "I(0) from standard fit (normalized to 1E8 monitor cts)"
2095        Prompt c5, "Standard Cross-Section (cm-1)"
2096       
2097        String/G root:myGlobals:Protocols:gAbsStr=""
2098       
2099        root:myGlobals:Protocols:gAbsStr = "TSTAND="+num2str(c2)
2100        root:myGlobals:Protocols:gAbsStr +=  ";" + "DSTAND="+num2str(c3)
2101        root:myGlobals:Protocols:gAbsStr +=  ";" + "IZERO="+num2str(c4)
2102        root:myGlobals:Protocols:gAbsStr +=  ";" + "XSECT="+num2str(c5)
2103       
2104End
2105
2106//asks the user for absolute scaling information. the user can either
2107//enter the 4 necessary values in manually (missing parameter dialog)
2108//or the user can select an empty beam file from a standard open dialog
2109//if an empty beam file is selected, the "kappa" value is automatically calculated
2110//in either case, the global keyword=value string is set.
2111//
2112//Proc AskForAbsoluteParams_Quest()
2113Function AskForAbsoluteParams_Quest()   
2114       
2115        Variable err, isNG5=0,loc,refnum
2116        //ask user if he wants to use a transmision file for absolute scaling
2117        //or if he wants to enter his own information
2118        DoAlert 1,"<Yes> to enter your own values, <No> to select an empty beam flux file"
2119        If ( (V_Flag==1) )
2120                //yes selected, prompt for values
2121                Execute "AskForAbsoluteParams()"                //missing parameters
2122        else
2123                //no selected, prompt for file, and use this to calculate KAPPA
2124                Variable kappa=1
2125               
2126                //ask for file and read it into RAW
2127                //will cancel if no file is selected
2128                err = ReadBinarySANS("select the empty beam file")              //reads and displays the RAW data
2129                if(err)
2130                        PathInfo/S catPathName
2131                        Abort "reduction sequence aborted"
2132                endif
2133                       
2134                Wave/T tw=$"root:RAW:TextRead"
2135                Wave rw=$"root:RAW:RealsRead"
2136                Wave iw=$"root:RAW:IntegersRead"
2137                String acctStr = tw[3]
2138                //NG5 attenuator transmission is assumed to be the same as the table for NG7
2139                       
2140                //get the necessary variables for the calculation of kappa
2141                Variable detCnt,countTime,attenTrans,monCnt,sdd,pixel
2142                String detStr=tw[9]
2143                pixel = DetectorPixelResolution(acctStr,detStr)         //get the pixel size from the file information
2144                countTime = iw[1]
2145                //detCnt = rw[2]                //080802 -use sum of data, not scaler from header
2146                monCnt = rw[0]
2147                sdd = rw[18]
2148                sdd *=100               //convert from meters to cm
2149                               
2150                //lookup table for transmission factor
2151                //determine which instrument the measurement was done on from acctStr
2152                Variable lambda = rw[26]
2153                Variable attenNo = rw[3]
2154                attenTrans = AttenuationFactor(acctStr,lambda,attenNo)
2155                //Print "attenTrans = ",attenTrans
2156               
2157                //get the XY box, if needed
2158                Variable x1,x2,y1,y2
2159                String filename=tw[0],tempStr
2160                err = GetXYBoxFromFile(filename,x1,x2,y1,y2)            //xy's are passed/returned by reference
2161                Print x1,x2,y1,y2
2162
2163                if( ((x1-x2)==0) || ((y1-y2)==0) )      //need to re-select the box
2164                        err = SelectABS_XYBox(x1,x2,y1,y2)              //this will pause for user input
2165                        if(err)
2166                                Abort "Box not selected properly - Please re-set the ABS parameters"
2167                        Endif
2168                        //box is OK, write box values to file (this does the same as SetXYBoxCoords)
2169                        String tempName = FindValidFilename(filename)
2170                        PathInfo/S catPathName
2171                        print S_Path + tempname
2172                        Open/A/T="????TEXT" refnum as (S_Path + tempname)
2173                        FSetPos refnum,478
2174                        FBinWrite/F=3/B=3 refNum, x1
2175                        FBinWrite/F=3/B=3 refNum, x2
2176                        FBinWrite/F=3/B=3 refNum, y1
2177                        FBinWrite/F=3/B=3 refNum, y2
2178                        //move to the end of the file before closing
2179                        FStatus refnum
2180                        FSetPos refnum,V_logEOF
2181                        Close refnum
2182                else
2183                        //give option to override
2184                        tempStr = "X=("+num2str(x1)+","+num2str(x2)+") Y=("+num2str(y1)+","+num2str(y2)+")"
2185                        DoAlert 1,"The current box is "+tempStr+".  Do you want to override these values?"
2186                        //Print v_flag
2187                        if(V_flag==1)   //1==yes, override
2188                                err = SelectABS_XYBox(x1,x2,y1,y2)
2189                                if(err)
2190                                        Abort "Box not selected properly -Please re-set the ABS parameters"
2191                                Endif
2192                        endif
2193                Endif
2194                Printf "Using Box X(%d,%d),Y(%d,%d)\r",x1,x2,y1,y2
2195               
2196                //need the detector sensitivity file - make a guess, allow to override
2197                String junkStr=""
2198                if(! waveexists($"root:DIV:data"))
2199                         junkStr = PromptForPath("Select the detector sensitivity file")
2200                        If(strlen(junkStr)==0)
2201                                SetDataFolder root:
2202                                Abort "No file selected, data reduction aborted"
2203                        Endif
2204                         ReadHeaderAndWork("DIV", junkStr)
2205                endif
2206                //toggle SANS_Data to linear display if needed, so that we're working with linear scaled data
2207                ControlInfo/W=SANS_Data bisLog
2208                if(V_Flag==1)
2209                        Log_Lin("bisLog")       
2210                endif   
2211                Wave divData = $"root:div:Data"
2212                Wave data = $"root:raw:data"            //this will be the linear data
2213                // correct by detector sensitivity
2214                data /= divData
2215               
2216                // now do the sum, only in the box     
2217//              detCnt = sum($"root:raw:data", -inf, inf )
2218//              Print "box is now ",x1,x2,y1,y2
2219                detCnt = SumCountsInBox(x1,x2,y1,y2,"RAW")
2220                //             
2221                kappa = detCnt/countTime/attenTrans*1.0e8/(monCnt/countTime)*(pixel/sdd)^2
2222                junkStr = num2str(kappa)
2223                // set the parameters in the global string
2224                Execute "AskForAbsoluteParams(1,1,"+junkStr+",1)"               //no missing parameters, no dialog
2225               
2226                //should wipe out the data in the RAW folder, since it's not really RAW now
2227                DoWindow/K SANS_Data
2228                // SRK JUL 2006 don't clear the contents - just kill the window to force new data to be loaded
2229                // - obsucre bug if "ask" in ABS section of protocol clears RAW folder, then Q-axes can't be set from RAW:RealsRead
2230                //ClearDataFolder("RAW")       
2231        Endif
2232        Print "Kappa was successfully calculated as = ",kappa
2233End
2234
2235//box coordinate are returned by reference
2236Function GetXYBoxFromFile(filename,x1,x2,y1,y2)
2237        String filename
2238        Variable &x1,&x2,&y1,&y2
2239       
2240        Variable refnum
2241        String emptyFile = FindValidFilename(filename)
2242       
2243//      Print emptyfile
2244       
2245        Open/R/P=catPathName refnum as emptyFile
2246        FSetPos refnum,478
2247        FBinRead/F=3/B=3 refnum, x1
2248        FBinRead/F=3/B=3 refnum, x2
2249        FBinRead/F=3/B=3 refnum, y1
2250        FBinRead/F=3/B=3 refnum, y2
2251        Close refnum
2252       
2253        return(0)
2254End
2255
2256Function UserSelectBox_Continue(ctrlName) :buttonControl
2257        String ctrlName
2258       
2259        DoWindow/K junkWindow           //kill panel
2260end
2261
2262Function SelectABS_XYBox(x1,x2,y1,y2)
2263        Variable &x1,&x2,&y1,&y2
2264       
2265        Variable err=0
2266       
2267        Variable/G root:V_marquee=1             //sets the sneaky bit to automatically update marquee coords
2268        Variable/G root:V_left,root:V_right,root:V_bottom,root:V_top    //must be global for auto-update
2269        DoWindow/F SANS_Data
2270        NewPanel/K=2 /W=(139,341,382,432) as "Select the primary beam"
2271        DoWindow/C junkWindow
2272        AutoPositionWindow/E/M=1/R=SANS_Data
2273       
2274        Drawtext 21,20 ,"Select the primary beam with the"
2275        DrawText 21,40, "marquee and press continue"
2276        Button button0,pos={80,58},size={92,20},title="Continue"
2277        Button button0,proc=UserSelectBox_Continue
2278       
2279        PauseForUser junkWindow,SANS_Data
2280       
2281        DoWindow/F SANS_Data
2282
2283        //GetMarquee left,bottom                        //not needed
2284        NVAR V_left=V_left
2285        NVAR V_right=V_right
2286        NVAR V_bottom=V_bottom
2287        NVAR V_top=V_top
2288       
2289        x1 = V_left
2290        x2 = V_right
2291        y1 = V_bottom
2292        y2 = V_top
2293//      Print "new values,before rounding = ",x1,x2,y1,y2
2294        KeepSelectionInBounds(x1,x2,y1,y2)
2295        //Print "new values = ",x1,x2,y1,y2
2296       
2297        KillVariables/Z root:V_Marquee,root:V_left,root:V_right,root:V_bottom,root:V_top
2298        if((x1-x2)==0 || (y1-y2)==0)
2299                err=1
2300        endif
2301        return(err)
2302End
2303
2304//save the protocol as an IGOR text wave (.itx)
2305//
2306//
2307Function ExportProtocol(ctrlName) : ButtonControl
2308        String ctrlName
2309// get a list of protocols
2310        String Protocol=""
2311        SetDataFolder root:myGlobals:Protocols
2312        Prompt Protocol "Pick A Protocol",popup, WaveList("*",";","")
2313        DoPrompt "Pick A Protocol to Export",Protocol
2314        if(V_flag==1)
2315                //Print "user cancel"
2316                SetDatafolder root:
2317                return(1)
2318        endif
2319//get the selection, or exit
2320        Wave/T pW= $protocol
2321        Make/O/T/N=13 tw
2322// save in the proper format (must write manually, for demo version)
2323        tw[0] = "IGOR"
2324        tw[1] = "WAVES/T \t"+protocol
2325        tw[2] = "BEGIN"
2326        tw[3,10] = "\t\""+pW[p-3]+"\""
2327        tw[11] = "END"
2328        tw[12] = "X SetScale/P x 0,1,\"\","+protocol+"; SetScale y 0,0,\"\","+protocol
2329       
2330        Variable refnum
2331        String fullPath
2332       
2333        PathInfo/S catPathName
2334        fullPath = DoSaveFileDialog("Export Protocol as")
2335        If(cmpstr(fullPath,"")==0)
2336                //user cancel, don't write out a file
2337                Close/A
2338                Abort "no Protocol file was written"
2339        Endif
2340
2341        //actually open the file
2342        Open refNum as fullpath+".itx"
2343       
2344        wfprintf refnum, "%s\r", tw
2345        Close refnum
2346        //Print "all is well  ",protocol
2347        KillWaves/Z tw
2348        setDataFolder root:
2349        return(0)
2350
2351End
2352
2353//imports a protocol from disk into the protocols folder
2354//
2355// will overwrite existing protocols if necessary
2356//
2357//
2358Function ImportProtocol(ctrlName) : ButtonControl
2359        String ctrlName
2360
2361        SetDataFolder root:myGlobals:Protocols
2362
2363        String fullPath
2364       
2365        PathInfo/S catPathName
2366        fullPath = DoOpenFileDialog("Import Protocol")
2367        If(cmpstr(fullPath,"")==0)
2368                //user cancel, don't write out a file
2369                Close/A
2370                Abort "no protocol was loaded"
2371        Endif
2372       
2373        LoadWave/O/T fullPath
2374       
2375        SetDataFolder root:
2376        return(0)
2377end
Note: See TracBrowser for help on using the repository browser.