source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/VSANS/V_PatchFiles.ipf @ 1243

Last change on this file since 1243 was 1243, checked in by srkline, 2 years ago

added some test procedures to make it easier to calculate and patch the corrected beam center to a series of files. This new method can be found under the VSANS menu.

Changed the mask drawing objects to be semi-transparent to allow easier masking of bad spots - since you can see what you're doing now.

  • Property svn:executable set to *
File size: 86.5 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma version=5.0
3#pragma IgorVersion = 7.00
4
5
6//////////////////////////////////
7//
8// TODO --  January 2107
9//
10// This is experimental, making the patch work with list boxes as "groups" of the Nexus file structure
11//
12// some of the groupings are more natural, some will need to be re-organized for the
13// more natural needs of what will typically be patched in the most common cases.
14//
15///////////////////////////////
16
17// TODOs have been inserted to comment out all of the calls that don't compile and need to be replaced
18
19// TODO
20// x- not all of the functions here have been prefixed with "V_", especially the action procedures from the panel
21//   so this cannot be opened with the SANS Reduction, or there will be clashes
22// -- same file load/reload issue as with other operations that read a field from the file. ANY read requires
23//   that the entire file is read in, even just to check and see if it's raw data... then there is a local
24//   copy present to confuse matters of what was actually written
25//
26// -- for the batch entering of fields, when all of the proper beam center values are determined, then
27//    all (2 x 9 = 18) of these values will need to be entered in all of the data files that "match" this
28//    "configuration" - however a configuration is to be defined and differentiated from other configurations.
29//
30// -- there may be other situations where batch entering needs are
31//               different, and this may lead to different interface choices
32//
33// -- need to add some mechanism (new panel?) to enter:
34//    -- box coordinates
35//    -- ABS parameters
36//    -- averaging options -- these will have new options versus SANS (binning panels, slit mode, etc.)
37//
38//
39// TODO:
40// V_fPatch_GroupID_catTable()
41//      V_fPatch_Purpose_catTable()
42//      V_fPatch_Intent_catTable()
43/// -- these three functions are part of a growing list for faster patching. edit the file catalog, and
44//    write out the contents of the column (vs. filename)
45// -- make a simple panel w/buttons (like the sort panel) to call these functions
46//
47
48//**************************
49//
50//procedures required to allow patching of raw vSANS data headers
51//information for the Patch Panel is stored in the root:Packages:NIST:VSANS:Globals:Patch subfolder
52//
53// writes changes directly to the raw data headers as requested
54// * note that if a data file is currently in a work folder, the (real) header on disk
55// will be updated, but the data in the (WORK) folder will not reflect these changes, unless
56// the data folder is first cleared and the data is re-loaded
57//
58//**************************
59
60//main entry procedure for displaying the Patch Panel
61//
62Proc V_PatchFiles()
63       
64        DoWindow/F V_Patch_Panel
65        If(V_flag == 0)
66                V_InitializePatchPanel()
67                //draw panel
68                V_Patch_Panel()
69        Endif
70End
71
72//initialization of the panel, creating the necessary data folder and global
73//variables if necessary -
74//
75// root:Packages:NIST:VSANS:Globals:
76Proc V_InitializePatchPanel()
77        //create the global variables needed to run the Patch Panel
78        //all are kept in root:Packages:NIST:VSANS:Globals:Patch
79        If( ! (DataFolderExists("root:Packages:NIST:VSANS:Globals:Patch"))  )
80                //create the data folder and the globals for BOTH the Patch and Trans panels
81                NewDataFolder/O root:Packages:NIST:VSANS:Globals:Patch
82        Endif
83        V_CreatePatchGlobals()          //re-create them every time (so text and radio buttons are correct)
84End
85
86//the data folder root:Packages:NIST:VSANS:Globals:Patch must exist
87//
88Proc V_CreatePatchGlobals()
89        //ok, create the globals
90        String/G root:Packages:NIST:VSANS:Globals:Patch:gPatchMatchStr = "*"
91        String/G root:Packages:NIST:VSANS:Globals:Patch:gPatchCurLabel = "no file selected"
92       
93        PathInfo catPathName
94        If(V_flag==1)
95                String dum = S_path
96                String/G root:Packages:NIST:VSANS:Globals:Patch:gCatPathStr = dum
97        else
98                String/G root:Packages:NIST:VSANS:Globals:Patch:gCatPathStr = "no path selected"
99        endif
100        String/G root:Packages:NIST:VSANS:Globals:Patch:gPatchList = "none"
101
102        Variable/G root:Packages:NIST:VSANS:Globals:Patch:gRadioVal = 1
103       
104
105        SetDataFolder root:Packages:NIST:VSANS:Globals:Patch:   
106        Make/O/T/N=(10,3) PP_ListWave
107        Make/O/B/N=(10,3) PP_SelWave
108        Make/O/T/N=3 PP_TitleWave
109       
110        PP_TitleWave = {"Ch?","Label","Value"}
111       
112        PP_SelWave[][0] = 2^5           // checkboxes
113        PP_SelWave[][2] = 2^1           // 3rd column editable
114       
115       
116        SetDataFolder root:
117       
118End
119
120
121//panel recreation macro for the PatchPanel...
122//
123Proc V_Patch_Panel()
124        PauseUpdate; Silent 1      // building window...
125        NewPanel /W=(533,50,1140,588)/K=2 as "Patch Raw VSANS Data Files"
126        DoWindow/C V_Patch_Panel
127//      ShowTools/A
128        SetDataFolder root:Packages:NIST:VSANS:Globals:Patch:
129
130       
131        ModifyPanel cbRGB=(11291,48000,3012)
132        ModifyPanel fixedSize=1
133        SetDrawLayer UserBack
134        DrawLine 7,30,422,30
135
136       
137        SetVariable PathDisplay,pos={77,7},size={310,13},title="Path"
138        SetVariable PathDisplay,help={"This is the path to the folder that will be used to find the SANS data while patching. If no files appear in the popup, make sure that this folder is set correctly"}
139        SetVariable PathDisplay,font="Courier",fSize=10
140        SetVariable PathDisplay,limits={-Inf,Inf,0},value= root:Packages:NIST:VSANS:Globals:Patch:gCatPathStr
141        Button PathButton,pos={2,3},size={70,20},proc=V_PickPathButton,title="Pick Path"
142        Button PathButton,help={"Select the folder containing the raw SANS data files"}
143        Button helpButton,pos={400,3},size={25,20},proc=V_ShowPatchHelp,title="?"
144        Button helpButton,help={"Show the help file for patching raw data headers"}
145        PopupMenu PatchPopup,pos={4,37},size={156,19},proc=V_PatchPopMenuProc,title="File(s) to Patch"
146        PopupMenu PatchPopup,help={"The displayed file is the one that will be edited. The entire list will be edited if \"Change All..\" is selected. \r If no items, or the wrong items appear, click on the popup to refresh. \r List items are selected from the file based on MatchString"}
147        PopupMenu PatchPopup,mode=1,popvalue="none",value= #"root:Packages:NIST:VSANS:Globals:Patch:gPatchList"
148
149        Button CHButton,pos={314,37},size={110,20},proc=V_ChangeHeaderButtonProc,title="Change Header"
150        Button CHButton,help={"This will change the checked values (ONLY) in the single file selected in the popup."}
151        SetVariable PMStr,pos={6,63},size={174,13},proc=V_SetMatchStrProc,title="Match String"
152        SetVariable PMStr,help={"Enter the search string to narrow the list of files. \"*\" is the wildcard character. After entering, \"pop\" the menu to refresh the file list."}
153        SetVariable PMStr,font="Courier",fSize=10
154        SetVariable PMStr,limits={-Inf,Inf,0},value= root:Packages:NIST:VSANS:Globals:Patch:gPatchMatchStr
155        Button ChAllButton,pos={245,60},size={180,20},proc=V_ChAllHeadersButtonProc,title="Change All Headers in List"
156        Button ChAllButton,help={"This will change the checked values (ONLY) in ALL of the files in the popup list, not just the top file. If the \"change\" checkbox for the item is not checked, nothing will be changed for that item."}
157        Button DoneButton,pos={450,60},size={110,20},proc=V_DoneButtonProc,title="Done Patching"
158        Button DoneButton,help={"When done Patching files, this will close this control panel."}
159        CheckBox check0,pos={18,80},size={40,15},title="Run #",value= 1,mode=1,proc=V_MatchCheckProc
160        CheckBox check1,pos={78,80},size={40,15},title="Text",value= 0,mode=1,proc=V_MatchCheckProc
161        CheckBox check2,pos={138,80},size={40,15},title="Group_ID",value= 0,mode=1,proc=V_MatchCheckProc
162
163        SetVariable curStr,pos={50,112},size={350,20},title="File Label:"
164        SetVariable curStr,help={"Label of current file in popup list"}
165        SetVariable curStr,font="Courier",fSize=10
166        SetVariable curStr,limits={-Inf,Inf,0},value= root:Packages:NIST:VSANS:Globals:Patch:gPatchCurLabel
167       
168        PopupMenu popup_0,pos={450,112},size={109,20},title="Detector Panel",proc=V_PatchPopMenuProc
169        PopupMenu popup_0,mode=1,popvalue="FL",value= #"\"FL;FR;FT;FB;ML;MR;MT;MB;B;\""
170
171
172        TabControl PatchTab,pos={20,140},size={570,380}
173        TabControl PatchTab,tabLabel(0)="Control",tabLabel(1)="Reduction",tabLabel(2)="Sample"
174        TabControl PatchTab,tabLabel(3)="Instrument",tabLabel(4)="Detectors",tabLabel(5)="PolSANS"
175        TabControl PatchTab,value=0,labelBack=(47748,57192,54093),proc=V_PatchTabProc
176
177
178        ListBox list0,pos={30,170.00},size={550.00,330},proc=V_PatchListBoxProc,frame=1
179        ListBox list0,fSize=10,userColumnResize= 1,listWave=PP_ListWave,selWave=PP_SelWave,titleWave=PP_TitleWave
180        ListBox list0,mode=2,widths={30,200}
181
182
183// put these in a tabbed? section for the 9 different panels
184// will it be able to patch all "FL" with the proper values, then all "FR", etc. to batchwise correct files?
185
186// TODO: add functions for these, make the intent a popup (since it's an enumerated type)
187
188//      PopupMenu popup_1,pos={42,base+14*step},size={109,20},title="File intent"
189//      PopupMenu popup_1,mode=1,popvalue="SCATTER",value= #"\"SCATTER;EMPTY;BLOCKED BEAM;TRANS;EMPTY BEAM;\""
190
191
192
193        SetDataFolder root:
194End
195
196//
197// function to control the display of the list box, based on the selection of the tab
198//
199Function V_PatchTabProc(name,tab)
200        String name
201        Variable tab
202       
203//      Print "name,number",name,tab
204        SetDataFolder root:Packages:NIST:VSANS:Globals:Patch:
205       
206        Wave/T PP_listWave = PP_ListWave
207        Wave PP_selWave = PP_selWave
208       
209        //clear the listWave and SelWave
210        PP_ListWave = ""
211        PP_SelWave = 0
212       
213        Variable nRows=1
214        // switch based on the tab number
215        switch(tab)     
216                case 0:
217                        //Print "tab 0 = CONTROL"
218                       
219                        V_FillListBox0(PP_ListWave,PP_SelWave)
220                        break           
221                case 1:
222                        //Print "tab 1 = REDUCTION"
223                       
224                        V_FillListBox1(PP_ListWave,PP_SelWave)
225                        break
226                case 2:
227                        //Print "tab 2 = SAMPLE"
228                       
229                        V_FillListBox2(PP_ListWave,PP_SelWave)
230                        break
231                case 3:
232                        //Print "tab 3 = INSTRUMENT"
233                       
234                        V_FillListBox3(PP_ListWave,PP_SelWave)
235                        break
236                case 4:
237                        //Print "tab 4 = DETECTORS"
238                       
239                        V_FillListBox4(PP_ListWave,PP_SelWave)
240                        break
241                case 5:
242                        //Print "tab 5 = POL_SANS"
243
244                        V_FillListBox5(PP_ListWave,PP_SelWave)
245                        break
246                default:                        // optional default expression executed
247                        SetDataFolder root:
248                        Abort "No tab found -- PatchTabProc"            // when no case matches
249        endswitch
250
251
252        SetDataFolder root:
253        return(0)
254End
255
256// fill list boxes based on the tab
257//
258// *** if the number of elements is changed, then be sure that the variable nRows is updated
259//    * this is the same procedure for all of the tabs
260//    * then be sure that the new listWave assignments are properly indexed
261//
262// CONTROL
263//
264Function V_FillListBox0(listWave,selWave)
265        Wave/T listWave
266        Wave selWave
267       
268        // trust that I'm getting a valid raw data file name from the popup
269        String fname
270        ControlInfo/W=V_Patch_Panel PatchPopup
271        If(strlen(S_value)==0 || cmpstr(S_Value,"none")==0)
272                Abort "no file selected in popup menu"          //null selection
273        else
274                fname = S_value                         //selection not null
275        Endif
276        //prepend path for read routine
277        PathInfo catPathName
278        fname = S_path + fname
279
280        Variable nRows = 3
281        Redimension/N=(nRows,3) ListWave
282        Redimension/N=(nRows,3) selWave
283        // clear the contents
284        listWave = ""
285        selWave = 0
286        SelWave[][0] = 2^5              // checkboxes
287        SelWave[][2] = 2^1              // 3rd column editable
288       
289       
290       
291        listWave[0][1] = "count_time (s)"
292        listWave[0][2] = num2str(V_getCount_time(fname))
293       
294        listWave[1][1] = "detector_counts"
295        listWave[1][2] = num2str(V_getDetector_counts(fname))
296       
297        listWave[2][1] = "monitor_counts"
298//      listWave[2][2] = num2str(V_getControlMonitorCount(fname))
299        listWave[2][2] = num2str(V_getBeamMonNormData(fname))
300       
301        return(0)
302End
303
304// fill list boxes based on the tab
305//
306// REDUCTION items
307//
308Function V_FillListBox1(listWave,selWave)
309        Wave/T listWave
310        Wave selWave
311
312        // trust that I'm getting a valid raw data file name from the popup
313        String fname
314        ControlInfo/W=V_Patch_Panel PatchPopup
315        If(strlen(S_value)==0 || cmpstr(S_Value,"none")==0)
316                Abort "no file selected in popup menu"          //null selection
317        else
318                fname = S_value                         //selection not null
319        Endif
320        //prepend path for read routine
321        PathInfo catPathName
322        fname = S_path + fname
323
324        Variable nRows = 14
325        Redimension/N=(nRows,3) ListWave
326        Redimension/N=(nRows,3) selWave
327        // clear the contents
328        listWave = ""
329        selWave = 0
330        SelWave[][0] = 2^5              // checkboxes
331        SelWave[][2] = 2^1              // 3rd column editable
332       
333       
334        listWave[0][1] = "empty_beam_file_name"
335        listWave[0][2] = V_getEmptyBeamFileName(fname)
336       
337        listWave[1][1] = "background_file_name"
338        listWave[1][2] = V_getBackgroundFileName(fname)
339       
340        listWave[2][1] = "empty_file_name"
341        listWave[2][2] = V_getEmptyFileName(fname)
342       
343        listWave[3][1] = "sensitivity_file_name"
344        listWave[3][2] = V_getSensitivityFileName(fname)
345       
346        listWave[4][1] = "mask_file_name"
347        listWave[4][2] = V_getMaskFileName(fname)
348       
349        listWave[5][1] = "transmission_file_name"
350        listWave[5][2] = V_getTransmissionFileName(fname)
351       
352        listWave[6][1] = "intent"
353        listWave[6][2] = V_getReduction_intent(fname)
354       
355        listWave[7][1] = "file_purpose"
356        listWave[7][2] = V_getReduction_purpose(fname)
357       
358        listWave[8][1] = "group_id (sample)"
359        listWave[8][2] = num2str(V_getSample_groupID(fname))
360       
361        listWave[9][1] = "Box Coordinates"
362        WAVE boxCoord = V_getBoxCoordinates(fname)
363        listWave[9][2] = V_NumWave2List(boxCoord,";")
364
365        listWave[10][1] = "box_count"
366        listWave[10][2] = num2str(V_getBoxCounts(fname))
367       
368        listWave[11][1] = "box_count_error"
369        listWave[11][2] = num2str(V_getBoxCountsError(fname))
370       
371        listWave[12][1] = "whole_trans"
372        listWave[12][2] = num2str(V_getSampleTransWholeDetector(fname))
373       
374        listWave[13][1] = "whole_trans_error"
375        listWave[13][2] = num2str(V_getSampleTransWholeDetErr(fname))   
376               
377       
378
379        return(0)
380End
381
382// fill list boxes based on the tab
383//
384// SAMPLE
385//
386Function V_FillListBox2(listWave,selWave)
387        Wave/T listWave
388        Wave selWave
389       
390        // trust that I'm getting a valid raw data file name from the popup
391        String fname
392        ControlInfo/W=V_Patch_Panel PatchPopup
393        If(strlen(S_value)==0 || cmpstr(S_Value,"none")==0)
394                Abort "no file selected in popup menu"          //null selection
395        else
396                fname = S_value                         //selection not null
397        Endif
398        //prepend path for read routine
399        PathInfo catPathName
400        fname = S_path + fname
401
402        Variable nRows = 4
403        Redimension/N=(nRows,3) ListWave
404        Redimension/N=(nRows,3) selWave
405        // clear the contents
406        listWave = ""
407        selWave = 0
408        SelWave[][0] = 2^5              // checkboxes
409        SelWave[][2] = 2^1              // 3rd column editable
410       
411       
412        listWave[0][1] = "description"
413        listWave[0][2] = V_getSampleDescription(fname)
414       
415        listWave[1][1] = "thickness [cm]"
416        listWave[1][2] = num2str(V_getSampleThickness(fname))
417       
418        listWave[2][1] = "transmission"
419        listWave[2][2] = num2str(V_getSampleTransmission(fname))
420       
421        listWave[3][1] = "transmission_error"
422        listWave[3][2] = num2str(V_getSampleTransError(fname))
423       
424
425
426        return(0)
427End
428
429// fill list boxes based on the tab
430//
431// INSTRUMENT
432//
433Function V_FillListBox3(listWave,selWave)
434        Wave/T listWave
435        Wave selWave
436       
437        // trust that I'm getting a valid raw data file name from the popup
438        String fname
439        ControlInfo/W=V_Patch_Panel PatchPopup
440        If(strlen(S_value)==0 || cmpstr(S_Value,"none")==0)
441                Abort "no file selected in popup menu"          //null selection
442        else
443                fname = S_value                         //selection not null
444        Endif
445        //prepend path for read routine
446        PathInfo catPathName
447        fname = S_path + fname
448
449        Variable nRows = 17
450        Redimension/N=(nRows,3) ListWave
451        Redimension/N=(nRows,3) selWave
452        // clear the contents
453        listWave = ""
454        selWave = 0
455        SelWave[][0] = 2^5              // checkboxes
456        SelWave[][2] = 2^1              // 3rd column editable
457
458//
459// TODO - the attenuation factor is always calculated from the table. How do I devise a method to
460// overrride this behavior if a factor needs to be forced to a new value (old table, lambda out of range, etc.)?
461//     
462// currently, this simply prevents anyone from "patching" the header, which really doesn't work as intended
463//
464        SelWave[0][0] += 2^7            // disable the checkbox for attenuator
465        SelWave[1][0] += 2^7            // disable the checkbox for attenuator_err
466       
467        listWave[0][1] = "attenuator_transmission"
468        listWave[0][2] = num2str(V_getAttenuator_transmission(fname))   
469       
470        listWave[1][1] = "attenuator_transmission_error"
471        listWave[1][2] = num2str(V_getAttenuator_trans_err(fname))     
472
473        listWave[2][1] = "monochromator type"
474        listWave[2][2] = V_getMonochromatorType(fname)
475       
476        listWave[3][1] = "wavelength (A)"
477        listWave[3][2] = num2str(V_getWavelength(fname))       
478       
479        listWave[4][1] = "wavelength_spread"
480        listWave[4][2] = num2str(V_getWavelength_spread(fname))
481       
482        listWave[5][1] = "Number of Guides OR COLLIMATION"
483        listWave[5][2] = V_getNumberOfGuides(fname)
484
485        listWave[6][1] = "distance (source aperture to GV) [cm]"
486        listWave[6][2] = num2str(V_getSourceAp_distance(fname))         
487
488        listWave[7][1] = "source aperture size [mm]"
489        listWave[7][2] = V_getSourceAp_size(fname)
490       
491        listWave[8][1] = "sample aperture size (internal) [mm]"
492        listWave[8][2] = V_getSampleAp_size(fname)
493
494        listWave[9][1] = "sample aperture(2) SHAPE (external)"
495        listWave[9][2] = V_getSampleAp2_shape(fname)
496               
497        listWave[10][1] = "sample aperture(2) diam (external) [cm]"
498        listWave[10][2] = num2str(V_getSampleAp2_size(fname))   
499       
500        listWave[11][1] = "sample aperture(2) height (external) [cm]"
501        listWave[11][2] = num2str(V_getSampleAp2_height(fname))
502
503        listWave[12][1] = "sample aperture(2) width (external) [cm]"
504        listWave[12][2] = num2str(V_getSampleAp2_width(fname)) 
505
506        listWave[13][1] = "beam stop diameter (Middle) [mm]"
507//      listWave[13][2] = num2str(V_getBeamStopC2_size(fname)) 
508        listWave[13][2] = num2str(V_IdentifyBeamstopDiameter(fname,"MR"))       
509       
510        listWave[14][1] = "beam stop diameter (Back) [mm]"
511//      listWave[14][2] = num2str(V_getBeamStopC3_size(fname)) 
512        listWave[14][2] = num2str(V_IdentifyBeamstopDiameter(fname,"B"))       
513
514        listWave[15][1] = "sample aperture(2) to gate valve [cm]"
515        listWave[15][2] = num2str(V_getSampleAp2_distance(fname))       
516
517        listWave[16][1] = "sample to gate valve [cm]"
518        listWave[16][2] = num2str(V_getSampleTableOffset(fname))       
519
520                               
521        return(0)
522End
523
524
525// fill list boxes based on the tab
526//
527// TODO -- is this all of the fields that I want to edit?
528//
529// DETECTORS
530//
531Function V_FillListBox4(listWave,selWave)
532        Wave/T listWave
533        Wave selWave
534       
535        // trust that I'm getting a valid raw data file name from the popup
536        String fname
537        ControlInfo/W=V_Patch_Panel PatchPopup
538        If(strlen(S_value)==0 || cmpstr(S_Value,"none")==0)
539                Abort "no file selected in popup menu"          //null selection
540        else
541                fname = S_value                         //selection not null
542        Endif
543        //prepend path for read routine
544        PathInfo catPathName
545        fname = S_path + fname
546
547        Variable nRows = 13
548        Redimension/N=(nRows,3) ListWave
549        Redimension/N=(nRows,3) selWave
550        // clear the contents
551        listWave = ""
552        selWave = 0
553        SelWave[][0] = 2^5              // checkboxes
554        SelWave[][2] = 2^1              // 3rd column editable
555       
556        ControlInfo popup_0                     // which detector panel?
557        String detStr = S_value
558       
559        listWave[0][1] = "beam_center_x [cm]"
560        listWave[0][2] = num2str(V_getDet_Beam_center_x(fname,detStr)) 
561
562        listWave[1][1] = "beam_center_y [cm]"
563        listWave[1][2] = num2str(V_getDet_Beam_center_y(fname,detStr)) 
564
565        listWave[2][1] = "distance (nominal) [cm]"
566        listWave[2][2] = num2str(V_getDet_NominalDistance(fname,detStr))       
567
568        listWave[3][1] = "integrated_count"
569        listWave[3][2] = num2str(V_getDet_IntegratedCount(fname,detStr))       
570
571        listWave[4][1] = "pixel_fwhm_x [cm]"
572        listWave[4][2] = num2str(V_getDet_pixel_fwhm_x(fname,detStr))   
573
574        listWave[5][1] = "pixel_fwhm_y [cm]"
575        listWave[5][2] = num2str(V_getDet_pixel_fwhm_y(fname,detStr))   
576
577        listWave[6][1] = "pixel_num_x"
578        listWave[6][2] = num2str(V_getDet_pixel_num_x(fname,detStr))   
579
580        listWave[7][1] = "pixel_num_y"
581        listWave[7][2] = num2str(V_getDet_pixel_num_y(fname,detStr))   
582
583        listWave[8][1] = "setback [cm]"
584        listWave[8][2] = num2str(V_getDet_TBSetback(fname,detStr))     
585
586        if(cmpstr(detStr,"B") == 0 ||cmpstr(detStr,"FR") == 0 || cmpstr(detStr,"FL") == 0 || cmpstr(detStr,"MR") == 0 || cmpstr(detStr,"ML") == 0)
587                listWave[9][1] = "lateral_offset [cm]"                  // "B" detector drops here
588                listWave[9][2] = num2str(V_getDet_LateralOffset(fname,detStr)) 
589        else   
590                listWave[9][1] = "vertical_offset [cm]"
591                listWave[9][2] = num2str(V_getDet_VerticalOffset(fname,detStr))
592        endif   
593
594        listWave[10][1] = "x_pixel_size [mm]"
595        listWave[10][2] = num2str(V_getDet_x_pixel_size(fname,detStr)) 
596
597        listWave[11][1] = "y_pixel_size [mm]"
598        listWave[11][2] = num2str(V_getDet_y_pixel_size(fname,detStr)) 
599
600        listWave[12][1] = "dead time (s) (back only)"
601        listWave[12][2] = num2str(V_getDetector_deadtime_B(fname,detStr))                       //returns 0 if not "B"
602
603        return(0)
604End
605
606
607// fill list boxes based on the tab
608//
609// TODO -- this all needs to be filled in, once I figure out what is needed
610//
611// PolSANS
612//
613Function V_FillListBox5(listWave,selWave)
614        Wave/T listWave
615        Wave selWave
616       
617        // trust that I'm getting a valid raw data file name from the popup
618        String fname
619        ControlInfo/W=V_Patch_Panel PatchPopup
620        If(strlen(S_value)==0 || cmpstr(S_Value,"none")==0)
621                Abort "no file selected in popup menu"          //null selection
622        else
623                fname = S_value                         //selection not null
624        Endif
625        //prepend path for read routine
626        PathInfo catPathName
627        fname = S_path + fname
628
629        Variable nRows = 3
630        Redimension/N=(nRows,3) ListWave
631        Redimension/N=(nRows,3) selWave
632        // clear the contents
633        listWave = ""
634        selWave = 0
635        SelWave[][0] = 2^5              // checkboxes
636        SelWave[][2] = 2^1              // 3rd column editable
637       
638       
639        listWave[0][1] = "count_time (s)"
640        listWave[0][2] = num2str(V_getCount_time(fname))       
641
642        return(0)
643End
644
645
646// TODO -- determine if I really need this --- I don't
647//  think I really have any reason to respond to events from list box actions
648//  or edits. the final action of patching is done with the button
649//
650Function V_PatchListBoxProc(lba) : ListBoxControl
651        STRUCT WMListboxAction &lba
652
653        Variable row = lba.row
654        Variable col = lba.col
655        WAVE/T/Z listWave = lba.listWave
656        WAVE/Z selWave = lba.selWave
657
658        switch( lba.eventCode )
659                case -1: // control being killed
660                        break
661                case 1: // mouse down
662                        break
663                case 3: // double click
664                        break
665                case 4: // cell selection
666                case 5: // cell selection plus shift key
667                        break
668                case 6: // begin edit
669                        break
670                case 7: // finish edit
671                        break
672                case 13: // checkbox clicked (Igor 6.2 or later)
673                        break
674        endswitch
675
676        return 0
677End
678
679
680
681
682
683
684//button action procedure to select the local path to the folder that
685//contains the vSANS data
686//sets catPathName, updates the path display and the popup of files (in that folder)
687//
688Function V_PickPathButton(PathButton) : ButtonControl
689        String PathButton
690       
691        // call the main procedure to set the data path
692        V_PickPath()
693       
694        //set the global string to the selected pathname
695        //set a local copy of the path for Patch
696        PathInfo/S catPathName
697   String dum = S_path
698        if (V_flag == 0)
699                //path does not exist - no folder selected
700                String/G root:Packages:NIST:VSANS:Globals:Patch:gCatPathStr = "no folder selected"
701        else
702                String/G root:Packages:NIST:VSANS:Globals:Patch:gCatPathStr = dum
703        endif
704       
705        //Update the pathStr variable box
706        ControlUpdate/W=V_Patch_Panel $"PathDisplay"
707       
708        //then update the popup list
709        // (don't update the list - not until someone enters a search critera) -- Jul09
710        //
711       
712        STRUCT WMSetVariableAction sva
713        sva.eventCode = 2       
714        V_SetMatchStrProc(sva)          //this is equivalent to finding everything, typical startup case
715
716        return(0)
717End
718
719//
720//returns a list of valid files (raw data, no version numbers, no averaged files)
721//that is semicolon delimited, and is suitable for display in a popup menu
722//
723Function/S V_xGetValidPatchPopupList()
724
725        //make sure that path exists
726        PathInfo catPathName
727        String path = S_path
728        if (V_flag == 0)
729                Abort "folder path does not exist - use Pick Path button"
730        Endif
731       
732        String newList = ""
733
734        newList = V_GetRawDataFileList()
735
736        //trim list to include only selected files
737        SVAR match = root:Packages:NIST:VSANS:Globals:Patch:gPatchMatchStr
738        if(strlen(match) == 0)          //if nothing is entered for a match string, return everything, rather than nothing
739                match = "*"
740        endif
741
742        newlist = V_MyMatchList(match,newlist,";")
743       
744        newList = SortList(newList,";",0)
745        Return(newList)
746End
747
748
749
750//
751// TODO:
752// -- test all of the filters to be sure they actually work properly.
753//   Run # filter works
754//   Text filter works
755//
756// -- SDD filter does not apply -- what is a better filter choice?
757// -- can I filter intent? group_id?
758// -- can't just search for "sample" - this returns everything
759//
760//
761//
762//
763//
764//returns a list of valid files (raw data, no version numbers, no averaged files)
765//that is semicolon delimited, and is suitable for display in a popup menu
766//
767// Uses Grep to look through the any text in the file, which includes the sample label
768// can be very slow across the network, as it re-pops the menu on a selection (since some folks don't hit
769// enter when inputing a filter string)
770//
771// - or -
772// a list or range of run numbers
773// - or -
774// a SDD (to within 0.001m)
775// - or -
776// * to get everything
777//
778//      NVAR gRadioVal= root:Packages:NIST:VSANS:Globals:Patch:gRadioVal
779 // 1== Run # (comma range OK)
780 // 2== Grep the text (SLOW)
781 // 3== filter by SDD (within 0.001 m)
782Function/S V_GetValidPatchPopupList()
783
784        //make sure that path exists
785        PathInfo catPathName
786        String path = S_path
787        if (V_flag == 0)
788                Abort "folder path does not exist - use Pick Path button"
789        Endif
790       
791        String newList = ""
792
793        newList = V_GetRawDataFileList()
794
795        //trim list to include only selected files
796        SVAR match = root:Packages:NIST:VSANS:Globals:Patch:gPatchMatchStr
797        if(strlen(match) == 0 || cmpstr(match,"*")==0)          //if nothing or "*" entered for a match string, return everything, rather than nothing
798                match = "*"
799        // old way, with simply a wildcard
800                newlist = V_MyMatchList(match,newlist,";")
801                newList = SortList(newList,";",0)
802                return(newList)
803        endif
804       
805        //loop through all of the files as needed
806
807       
808        String list="",item="",fname,runList="",numStr=""
809        Variable ii,num=ItemsInList(newList),val,group_id
810        NVAR gRadioVal= root:Packages:NIST:VSANS:Globals:Patch:gRadioVal
811       
812        // run number list
813        if(gRadioVal == 1)
814                       
815                list = V_ExpandNumRanges(match)         //now simply comma delimited
816                num=ItemsInList(list,",")
817                for(ii=0;ii<num;ii+=1)
818                        item = StringFromList(ii,list,",")
819                        val=str2num(item)
820
821                        runList += V_GetFileNameFromPathNoSemi(V_FindFileFromRunNumber(val)) + ";"             
822                endfor
823                newlist = runList
824               
825        endif
826       
827        //grep through what text I can find in the VAX binary
828        // Grep Note: the \\b sequences limit matches to a word boundary before and after
829        // "boondoggle", so "boondoggles" and "aboondoggle" won't match.
830        if(gRadioVal == 2)
831                for(ii=0;ii<num;ii+=1)
832                        item=StringFromList(ii, newList , ";")
833//                      Grep/P=catPathName/Q/E=("(?i)\\b"+match+"\\b") item
834                        Grep/P=catPathName/Q/E=("(?i)"+match) item
835                        if( V_value )   // at least one instance was found
836//                              Print "found ", item,ii
837                                list += item + ";"
838                        endif
839                endfor
840
841                newList = list
842        endif
843       
844        // group_id
845        // replace this with: V_getSample_GroupID(fname)
846        Variable pos
847        String IDStr=""
848        if(gRadioVal == 3)
849                pos = strsearch(match, "*", 0)
850                if(pos == -1)           //no wildcard
851                        val = str2num(match)
852                else
853                        val = str2num(match[0,pos-1])
854                endif
855               
856//              print val
857                for(ii=0;ii<num;ii+=1)
858                        item=StringFromList(ii, newList , ";")
859                        fname = path + item
860                        group_id = V_getSample_GroupID(fname)
861                        if(group_id == val)
862                                list += item + ";"
863                        endif
864       
865                endfor
866               
867                newList = list
868        endif
869
870        newList = SortList(newList,";",0)
871        Return(newList)
872End
873
874
875
876
877// -- no longer refreshes the list - this seems redundant, and can be slow if grepping
878//
879//updates the popup list when the menu is "popped" so the list is
880//always fresh, then automatically displays the header of the popped file
881//value of match string is used in the creation of the list - use * to get
882//all valid files
883//
884Function V_PatchPopMenuProc(PatchPopup,popNum,popStr) : PopupMenuControl
885        String PatchPopup
886        Variable popNum
887        String popStr
888
889       
890//      String/G root:Packages:NIST:VSANS:Globals:Patch:gPatchList = list
891//      ControlUpdate PatchPopup
892        V_ShowHeaderButtonProc("SHButton")
893       
894        return(0)
895End
896
897
898//when text is entered in the match string, the popup list is refined to
899//include only the selected files, useful for trimming a lengthy list, or selecting
900//a range of files to patch
901//only one wildcard (*) is allowed
902//
903//change the contents of gPatchList that is displayed
904//based on selected Path, match str, and
905//further trim list to include only RAW SANS files
906//this will exclude version numbers, .AVE, .ABS files, etc. from the popup (which can't be patched)
907Function V_SetMatchStrProc(sva) : SetVariableControl
908        STRUCT WMSetVariableAction &sva
909
910        switch( sva.eventCode )
911                case 1: // mouse up
912                case 2: // Enter key
913                case 8:         // edit end
914                        Variable dval = sva.dval
915                        String sval = sva.sval
916                       
917                        String list = V_GetValidPatchPopupList()
918       
919                        String/G root:Packages:NIST:VSANS:Globals:Patch:gPatchList = list
920                        ControlUpdate PatchPopup
921                        PopupMenu PatchPopup,mode=1
922                       
923                        if(strlen(list) > 0)
924                                V_ShowHeaderButtonProc("SHButton")
925                        endif
926                case 3: // Live update
927
928                        break
929                case -1: // control being killed
930                        break
931        endswitch
932
933        return 0
934End
935
936//displays the header of the selected file (top in the popup) when the button is clicked
937//sort of a redundant button, since the procedure is automatically called (as if it were
938//clicked) when a new file is chosen from the popup
939//
940// TODO - make sure this is tab-aware
941//
942Function V_ShowHeaderButtonProc(SHButton) : ButtonControl
943        String SHButton
944
945        //displays (editable) header information about current file in popup control
946        //putting the values in the SetVariable displays (resetting the global variables)
947       
948        //get the popup string
949        String partialName, tempName
950        Variable ok
951        ControlInfo/W=V_Patch_Panel PatchPopup
952        If(strlen(S_value)==0 || cmpstr(S_Value,"none")==0)
953                //null selection
954                Abort "no file selected in popup menu"
955        else
956                //selection not null
957                partialName = S_value
958                //Print partialName
959        Endif
960        //get a valid file based on this partialName and catPathName
961        tempName = V_FindValidFilename(partialName)
962       
963        //prepend path to tempName for read routine
964        PathInfo catPathName
965        tempName = S_path + tempName
966       
967        //make sure the file is really a RAW data file
968        ok = V_CheckIfRawData(tempName)                 //--- This loads the whole file to read the instrument string
969        if (!ok)
970                Abort "this file is not recognized as a RAW SANS data file"
971        Endif
972       
973        //Print tempName
974       
975        V_ReadHeaderForPatch(tempName)
976       
977        ControlUpdate/A/W=V_Patch_Panel
978       
979        // no matter what tab is selected, show the file label
980        SVAR fileLabel = root:Packages:NIST:VSANS:Globals:Patch:gPatchCurLabel
981        fileLabel = V_getSampleDescription(tempName)
982       
983        return(0)
984End
985
986
987
988//simple function to get the string value from the popup list of filenames
989//returned string is only the text in the popup, a partial name with no path
990//or VAX version number.
991//
992Function/S V_GetPatchPopupString()
993
994        String str=""
995       
996        ControlInfo patchPopup
997        If(cmpstr(S_value,"")==0)
998                //null selection
999                Abort "no file selected in popup menu"
1000        else
1001                //selection not null
1002                str = S_value
1003                //Print str
1004        Endif
1005       
1006        Return str
1007End
1008
1009//Changes (writes to disk!) the specified changes to the (single) file selected in the popup
1010//reads the checkboxes to determine which (if any) values need to be written
1011//
1012// This currently makes sure the name is valid,
1013// determines the active tab,
1014// and dispatches to the correct (numbered) writer
1015//
1016Function V_ChangeHeaderButtonProc(CHButton) : ButtonControl
1017        String CHButton
1018
1019        String partialName="", tempName = ""
1020        Variable ok
1021        //get the popup string
1022        partialName = V_GetPatchPopupString()
1023       
1024        //get a valid file based on this partialName and catPathName
1025        tempName = V_FindValidFilename(partialName)
1026       
1027        //prepend path to tempName for read routine
1028        PathInfo catPathName
1029        tempName = S_path + tempName
1030       
1031        //make sure the file is really a RAW data file
1032        ok = V_CheckIfRawData(tempName)
1033        if (!ok)
1034                Abort "this file is not recognized as a RAW SANS data file"
1035        Endif
1036       
1037        // which tab is active?
1038        ControlInfo/W=V_Patch_Panel PatchTab
1039       
1040        switch(V_Value) // numeric switch
1041                case 0: // execute if case matches expression
1042                        V_WriteHeaderForPatch_0(tempName)               //control
1043                        break           // exit from switch
1044                case 1:
1045                        V_WriteHeaderForPatch_1(tempName)               //reduction
1046                        break
1047                case 2:
1048                        V_WriteHeaderForPatch_2(tempName)               // sample
1049                        break
1050                case 3:
1051                        V_WriteHeaderForPatch_3(tempName)               // instrument
1052                        break
1053                case 4:
1054                        V_WriteHeaderForPatch_4(tempName)               //detectors
1055                        break
1056                case 5:
1057                        V_WriteHeaderForPatch_5(tempName)               // polSANS
1058                        break
1059                default:                        // optional default expression executed
1060                        Abort "Tab not found - V_ChangeHeaderButtonProc"
1061        endswitch
1062
1063       
1064        //after writing the changes to the file
1065        // clean up, to force a reload from disk
1066        V_CleanupData_w_Progress(0,1)
1067       
1068        return(0)
1069End
1070
1071//     
1072//*****this function actually writes the data to disk*****
1073//
1074// DONE x- re-write a series of these function to mirror the "fill" functions
1075//   specific to each tab
1076//
1077// DONE x- clear out the old data and force a re-load from disk, or the old data
1078//    will be read in from the RawVSANS folder, and it will look like nothing was written
1079//                      (done in the calling function)
1080//
1081// currently, all errors are printed out by the writer, but ignored here
1082//
1083Function V_WriteHeaderForPatch_0(fname)
1084        String fname
1085       
1086        Variable val,err
1087        String textstr
1088               
1089        Wave/T listWave = root:Packages:NIST:VSANS:Globals:Patch:PP_ListWave
1090        Wave selWave = root:Packages:NIST:VSANS:Globals:Patch:PP_selWave
1091
1092        // test bit 4 to see if the checkbox is selected
1093        if ((selWave[0][0] & 2^4) != 0)         // Test if bit 4 is set
1094                val = str2num(listWave[0][2])
1095                err = V_writeCount_time(fname,val)              // count_time
1096        endif
1097
1098        if ((selWave[1][0] & 2^4) != 0)         // "detector_counts"
1099                val = str2num(listWave[1][2])
1100                err = V_writeDetector_counts(fname,val)
1101        endif   
1102       
1103        if ((selWave[2][0] & 2^4) != 0)         //"monitor_counts"
1104                val = str2num(listWave[2][2])
1105//              err = V_writeControlMonitorCount(fname,val)
1106                err = V_writeBeamMonNormData(fname,val)
1107        endif   
1108       
1109
1110
1111
1112        Return(0)
1113End
1114
1115//
1116// tab 1
1117//
1118Function V_WriteHeaderForPatch_1(fname)
1119        String fname
1120
1121        Variable val,err
1122        String str
1123               
1124        Wave/T listWave = root:Packages:NIST:VSANS:Globals:Patch:PP_ListWave
1125        Wave selWave = root:Packages:NIST:VSANS:Globals:Patch:PP_selWave
1126
1127        // test bit 4 to see if the checkbox is selected
1128        if ((selWave[0][0] & 2^4) != 0)         // Test if bit 4 is set
1129                str = listWave[0][2]                    // empty_beam_file_name
1130                err = V_writeEmptyBeamFileName(fname,str)               
1131        endif
1132
1133        if ((selWave[1][0] & 2^4) != 0)         // "background_file_name"
1134                str = listWave[1][2]
1135                err = V_writeBackgroundFileName(fname,str)
1136        endif   
1137       
1138        if ((selWave[2][0] & 2^4) != 0)         //"empty_file_name"
1139                str = listWave[2][2]
1140                err = V_writeEmptyFileName(fname,str)
1141        endif   
1142       
1143        if ((selWave[3][0] & 2^4) != 0)         //"sensitivity_file_name"
1144                str = listWave[3][2]
1145                err = V_writeSensitivityFileName(fname,str)
1146        endif   
1147       
1148        if ((selWave[4][0] & 2^4) != 0)         //"mask_file_name"
1149                str = listWave[4][2]
1150                err = V_writeMaskFileName(fname,str)
1151        endif   
1152       
1153        if ((selWave[5][0] & 2^4) != 0)         //"transmission_file_name"
1154                str = listWave[5][2]
1155                err = V_writeTransmissionFileName(fname,str)
1156        endif   
1157
1158        if ((selWave[6][0] & 2^4) != 0)         //"intent"
1159                str = listWave[6][2]
1160                err = V_writeReductionIntent(fname,str)
1161        endif   
1162       
1163        if ((selWave[7][0] & 2^4) != 0)         //"file_purpose"
1164                str = listWave[7][2]
1165                err = V_writeReduction_purpose(fname,str)
1166        endif           
1167
1168        if ((selWave[8][0] & 2^4) != 0)         //"group_id (sample)"
1169                val = str2num(listWave[8][2])
1170                err = V_writeSample_GroupID(fname,val)
1171        endif   
1172
1173
1174
1175        if ((selWave[9][0] & 2^4) != 0)         //"box coordinates"
1176                str = listWave[9][2]
1177                err = V_writeBoxCoordinates(fname,V_List2NumWave(str,";","inW"))
1178        endif   
1179       
1180
1181       
1182        if ((selWave[10][0] & 2^4) != 0)                //"box_count"
1183                val = str2num(listWave[10][2])
1184                err = V_writeBoxCounts(fname,val)
1185        endif   
1186       
1187        if ((selWave[11][0] & 2^4) != 0)                //"box_count_error"
1188                val = str2num(listWave[11][2])
1189                err = V_writeBoxCountsError(fname,val)
1190        endif   
1191       
1192        if ((selWave[12][0] & 2^4) != 0)                //"whole_trans"
1193                val = str2num(listWave[12][2])
1194                err = V_writeSampleTransWholeDetector(fname,val)
1195        endif   
1196       
1197        if ((selWave[13][0] & 2^4) != 0)                //"whole_trans_error"
1198                val = str2num(listWave[13][2])
1199                err = V_writeSampleTransWholeDetErr(fname,val)
1200        endif   
1201       
1202       
1203               
1204               
1205        return(0)
1206End
1207
1208// SAMPLE
1209Function V_WriteHeaderForPatch_2(fname)
1210        String fname
1211       
1212        Variable val,err
1213        String str
1214               
1215        Wave/T listWave = root:Packages:NIST:VSANS:Globals:Patch:PP_ListWave
1216        Wave selWave = root:Packages:NIST:VSANS:Globals:Patch:PP_selWave
1217
1218        // test bit 4 to see if the checkbox is selected
1219        if ((selWave[0][0] & 2^4) != 0)         // Test if bit 4 is set
1220                str = listWave[0][2]                    // "description"
1221                err = V_writeSampleDescription(fname,str)               
1222        endif
1223
1224        if ((selWave[1][0] & 2^4) != 0)         // "thickness"
1225                val = str2num(listWave[1][2])
1226                err = V_writeSampleThickness(fname,val)
1227        endif   
1228       
1229        if ((selWave[2][0] & 2^4) != 0)         //"transmission"
1230                val = str2num(listWave[2][2])
1231                err = V_writeSampleTransmission(fname,val)
1232        endif   
1233       
1234        if ((selWave[3][0] & 2^4) != 0)         //"transmission_error"
1235                val = str2num(listWave[3][2])
1236                err = V_writeSampleTransError(fname,val)
1237        endif   
1238       
1239        return(0)
1240End
1241
1242// INSTRUMENT
1243Function V_WriteHeaderForPatch_3(fname)
1244        String fname
1245
1246        Variable val,err
1247        String str
1248               
1249        Wave/T listWave = root:Packages:NIST:VSANS:Globals:Patch:PP_ListWave
1250        Wave selWave = root:Packages:NIST:VSANS:Globals:Patch:PP_selWave
1251
1252        // test bit 4 to see if the checkbox is selected
1253        if ((selWave[0][0] & 2^4) != 0)         // Test if bit 4 is set
1254                val = str2num(listWave[0][2])                   // "attenuator_transmission"
1255                err = V_writeAttenuator_transmission(fname,val)         
1256        endif
1257
1258        if ((selWave[1][0] & 2^4) != 0)         // "attenuator_transmission_error"
1259                val = str2num(listWave[1][2])
1260                err = V_writeAttenuator_trans_err(fname,val)
1261        endif   
1262       
1263        if ((selWave[2][0] & 2^4) != 0)         //"monochromator type"
1264                str = listWave[2][2]
1265                err = V_writeMonochromatorType(fname,str)
1266        endif   
1267       
1268        if ((selWave[3][0] & 2^4) != 0)         //"wavelength"
1269                val = str2num(listWave[3][2])
1270                err = V_writeWavelength(fname,val)
1271        endif   
1272
1273        if ((selWave[4][0] & 2^4) != 0)         //"wavelength_spread"
1274                val = str2num(listWave[4][2])
1275                err = V_writeWavelength_spread(fname,val)
1276        endif   
1277
1278        if ((selWave[5][0] & 2^4) != 0)         //"number of guides (a string value)"
1279                str = listWave[5][2]
1280                err = V_writeNumberOfGuides(fname,str)
1281        endif           
1282       
1283        if ((selWave[6][0] & 2^4) != 0)         //"distance (source aperture)"
1284                val = str2num(listWave[6][2])
1285                err = V_writeSourceAp_distance(fname,val)
1286        endif           
1287
1288        if ((selWave[7][0] & 2^4) != 0)         //"source aperture size [mm]" (a string with units)
1289                str = listWave[7][2]
1290                err = V_writeSourceAp_size(fname,str)
1291        endif           
1292
1293        if ((selWave[8][0] & 2^4) != 0)         //"sample aperture size (internal) [mm]" (a string with units)
1294                str = listWave[8][2]
1295                err = V_writeSampleAp_size(fname,str)
1296        endif   
1297
1298        if ((selWave[9][0] & 2^4) != 0)         //"sample aperture SHAPE (external) [cm]"
1299                str = listWave[9][2]
1300                err = V_writeSampleAp2_shape(fname,str)
1301        endif           
1302       
1303        if ((selWave[10][0] & 2^4) != 0)                //"sample aperture diam (external) [cm]"
1304                val = str2num(listWave[10][2])
1305                err = V_writeSampleAp2_size(fname,val)
1306        endif           
1307       
1308        if ((selWave[11][0] & 2^4) != 0)                //"sample aperture height (external) [cm]"
1309                val = str2num(listWave[11][2])
1310                err = V_writeSampleAp2_height(fname,val)
1311        endif           
1312               
1313        if ((selWave[12][0] & 2^4) != 0)                //"sample aperture width (external) [cm]"
1314                val = str2num(listWave[12][2])
1315                err = V_writeSampleAp2_width(fname,val)
1316        endif           
1317
1318        if ((selWave[13][0] & 2^4) != 0)                //"beam stop diameter (Middle) [mm]"
1319                val = str2num(listWave[13][2])
1320                err = V_writeBeamStopC2_size(fname,val)
1321        endif           
1322       
1323        if ((selWave[14][0] & 2^4) != 0)                //"beam stop diameter (Back) [mm]"
1324                val = str2num(listWave[14][2])
1325                err = V_writeBeamStopC3_size(fname,val)
1326        endif           
1327
1328        if ((selWave[15][0] & 2^4) != 0)                //"sample aperture to gate valve [cm]"
1329                val = str2num(listWave[15][2])
1330                err = V_writeSampleAp_distance(fname,val)
1331        endif   
1332
1333        if ((selWave[16][0] & 2^4) != 0)                //"sample to gate valve [cm]"
1334                val = str2num(listWave[16][2])
1335                err = V_writeSampleTableOffset(fname,val)
1336        endif           
1337       
1338        return(0)
1339End
1340
1341// DETECTOR
1342Function V_WriteHeaderForPatch_4(fname)
1343        String fname
1344
1345        Variable val,err
1346        String str
1347               
1348        Wave/T listWave = root:Packages:NIST:VSANS:Globals:Patch:PP_ListWave
1349        Wave selWave = root:Packages:NIST:VSANS:Globals:Patch:PP_selWave
1350
1351        ControlInfo popup_0
1352        String detStr = S_Value
1353
1354        // test bit 4 to see if the checkbox is selected
1355        if ((selWave[0][0] & 2^4) != 0)         // Test if bit 4 is set
1356                val = str2num(listWave[0][2])                   // "beam_center_x"
1357                err = V_writeDet_beam_center_x(fname,detStr,val)       
1358        endif
1359
1360        if ((selWave[1][0] & 2^4) != 0)         // "beam_center_y"
1361                val = str2num(listWave[1][2])
1362                err = V_writeDet_beam_center_y(fname,detStr,val)
1363        endif   
1364       
1365        if ((selWave[2][0] & 2^4) != 0)         //"distance (nominal)"
1366                val = str2num(listWave[2][2])
1367                err = V_writeDet_distance(fname,detStr,val)
1368        endif   
1369       
1370        if ((selWave[3][0] & 2^4) != 0)         //"integrated_count"
1371                val = str2num(listWave[3][2])
1372                err = V_writeDet_IntegratedCount(fname,detStr,val)
1373        endif   
1374       
1375        if ((selWave[4][0] & 2^4) != 0)         //"pixel_fwhm_x"
1376                val = str2num(listWave[4][2])
1377                err = V_writeDet_pixel_fwhm_x(fname,detStr,val)
1378        endif   
1379       
1380        if ((selWave[5][0] & 2^4) != 0)         //"pixel_fwhm_y"
1381                val = str2num(listWave[5][2])
1382                err = V_writeDet_pixel_fwhm_y(fname,detStr,val)
1383        endif   
1384
1385        if ((selWave[6][0] & 2^4) != 0)         //"pixel_num_x"
1386                val = str2num(listWave[6][2])
1387                err = V_writeDet_pixel_num_x(fname,detStr,val)
1388        endif   
1389       
1390        if ((selWave[7][0] & 2^4) != 0)         //"pixel_num_y"
1391                val = str2num(listWave[7][2])
1392                err = V_writeDet_pixel_num_y(fname,detStr,val)
1393        endif           
1394       
1395        if ((selWave[8][0] & 2^4) != 0)         //"setback" -- only for TB detectors
1396                val = str2num(listWave[8][2])
1397                if(cmpstr(detStr,"FT") == 0 || cmpstr(detStr,"FB") == 0 || cmpstr(detStr,"MT") == 0 || cmpstr(detStr,"MB") == 0)
1398                        err = V_writeDet_TBSetback(fname,detStr,val)
1399                endif
1400        endif   
1401
1402        if ((selWave[9][0] & 2^4) != 0)         //"lateral_offset" or "vertical_offset"
1403                val = str2num(listWave[9][2])
1404                if(cmpstr(detStr,"B") == 0 ||cmpstr(detStr,"FR") == 0 || cmpstr(detStr,"FL") == 0 || cmpstr(detStr,"MR") == 0 || cmpstr(detStr,"ML") == 0)
1405                        err = V_writeDet_LateralOffset(fname,detStr,val)
1406                else
1407                        err = V_writeDet_VerticalOffset(fname,detStr,val)
1408                endif
1409        endif   
1410       
1411        if ((selWave[10][0] & 2^4) != 0)                //"x_pixel_size"
1412                val = str2num(listWave[10][2])
1413                err = V_writeDet_x_pixel_size(fname,detStr,val)
1414        endif   
1415       
1416        if ((selWave[11][0] & 2^4) != 0)                //"y_pixel_size"
1417                val = str2num(listWave[11][2])
1418                err = V_writeDet_y_pixel_size(fname,detStr,val)
1419        endif   
1420       
1421        if ((selWave[12][0] & 2^4) != 0)                //"dead time, "B" only"
1422                val = str2num(listWave[12][2])
1423                if(cmpstr(detStr,"B") == 0)
1424                        err = V_writeDetector_deadtime_B(fname,detStr,val)
1425                endif
1426        endif   
1427
1428       
1429        return(0)
1430End
1431
1432// TODO -- not yet implemented
1433Function V_WriteHeaderForPatch_5(fname)
1434        String fname
1435       
1436        return(0)
1437End
1438
1439
1440// control the display of the radio buttons
1441Function V_MatchCheckProc(name,value)
1442        String name
1443        Variable value
1444       
1445        NVAR gRadioVal= root:Packages:NIST:VSANS:Globals:Patch:gRadioVal
1446       
1447        strswitch (name)
1448                case "check0":
1449                        gRadioVal= 1
1450                        break
1451                case "check1":
1452                        gRadioVal= 2
1453                        break
1454                case "check2":
1455                        gRadioVal= 3
1456                        break
1457        endswitch
1458        CheckBox check0,value= gRadioVal==1
1459        CheckBox check1,value= gRadioVal==2
1460        CheckBox check2,value= gRadioVal==3
1461        return(0)
1462End
1463
1464//This function will read only the selected values editable in the patch panel
1465//
1466// DONE
1467// x- re-write this to be tab-aware. ShowHeaderForPatch() calls this, but does nothing
1468//    to update the tab content. Figure out which function is in charge, and update the content.
1469//
1470Function V_ReadHeaderForPatch(fname)
1471        String fname
1472       
1473       
1474        // figure out which is the active tab, then let PatchTabProc fill it in
1475        ControlInfo/W=V_Patch_Panel PatchTab
1476        V_PatchTabProc("",V_Value)     
1477       
1478        Return 0
1479End
1480
1481Function V_ShowPatchHelp(ctrlName) : ButtonControl
1482        String ctrlName
1483        DisplayHelpTopic/Z/K=1 "VSANS Data Reduction Documentation[Patch File Headers]"
1484        if(V_flag !=0)
1485                DoAlert 0,"The VSANS Data Reduction Tutorial Help file could not be found"
1486        endif
1487        return(0)
1488End
1489
1490//button action procedure to change the selected information (checked values)
1491//in each file in the popup list. This will change multiple files, and as such,
1492//the user is given a chance to bail out before the whole list of files
1493//is modified
1494//useful for patching a series of runs with the same beamcenters, or transmissions
1495//
1496Function V_ChAllHeadersButtonProc(ctrlName) : ButtonControl
1497        String ctrlName
1498       
1499        String msg
1500        msg = "Do you really want to write all of these values to each data file in the popup list? "
1501        msg += "- clicking NO will leave all files unchanged"
1502        DoAlert 1,msg
1503        If(V_flag == 2)
1504                Abort "no files were changed"
1505        Endif
1506       
1507        //this will change (checked) values in ALL of the headers in the popup list
1508        SVAR list = root:Packages:NIST:VSANS:Globals:Patch:gPatchList
1509        Variable numitems,ii
1510        String partialName="", tempName = ""
1511        Variable ok
1512       
1513        numitems = ItemsInList(list,";")
1514       
1515        if(numitems == 0)
1516                Abort "no items in list for multiple patch"
1517        Endif
1518       
1519        // loop through all of the files
1520        ii=0
1521        do
1522                //get current item in the list
1523                partialName = StringFromList(ii, list, ";")
1524                   
1525                //get a valid file based on this partialName and catPathName
1526                tempName = V_FindValidFilename(partialName)
1527       
1528                //prepend path to tempName for read routine
1529                PathInfo catPathName
1530                tempName = S_path + tempName
1531       
1532                //make sure the file is really a RAW data file
1533                ok = V_CheckIfRawData(tempName)
1534                if (!ok)
1535                   Print "this file is not recognized as a RAW SANS data file = ",tempName
1536                else
1537                   //go write the changes to the file
1538                        // which tab is active?
1539                        ControlInfo/W=V_Patch_Panel PatchTab
1540                       
1541                        switch(V_Value) // numeric switch
1542                                case 0: // execute if case matches expression
1543                                        V_WriteHeaderForPatch_0(tempName)
1544                                        break           // exit from switch
1545                                case 1:
1546                                        V_WriteHeaderForPatch_1(tempName)
1547                                        break
1548                                case 2:
1549                                        V_WriteHeaderForPatch_2(tempName)
1550                                        break
1551                                case 3:
1552                                        V_WriteHeaderForPatch_3(tempName)
1553                                        break
1554                                case 4:
1555                                        V_WriteHeaderForPatch_4(tempName)
1556                                        break
1557                                case 5:
1558                                        V_WriteHeaderForPatch_5(tempName)
1559                                        break
1560                                default:                        // optional default expression executed
1561                                        Abort "Tab not found - V_ChAllHeadersButtonProc"
1562                        endswitch
1563                Endif
1564               
1565                ii+=1
1566        while(ii<numitems)
1567
1568
1569        //after writing the changes to the file
1570        // clean up, to force a reload from disk
1571        V_CleanupData_w_Progress(0,1)
1572
1573        return(0)
1574End
1575
1576
1577//simple action for button to close the panel
1578//
1579// cleans out the RawVSANS folder on closing
1580//
1581Function V_DoneButtonProc(ctrlName) : ButtonControl
1582        String ctrlName
1583
1584        DoWindow/K V_Patch_Panel
1585
1586//      V_CleanOutRawVSANS()
1587// present a progress window
1588        V_CleanupData_w_Progress(0,1)   
1589       
1590        return(0)
1591End
1592
1593
1594
1595////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1596////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1597///////////////
1598//
1599// this is a block to patch DEADTIME waves to the file headers, and can patch multiple files
1600//
1601// uses a simple panel to show what the table of values is.
1602// "read" will read only the first run number contents.
1603//
1604// TODO -- need to clear out the contents from RawVSANS, or else re-reading to check the values
1605//        will read locally, and it will look like nothing was written. Executing "save" will also
1606//        trigger a cleanout.
1607//
1608// TODO -- link this to a panel somewhere - a button? menu item? will there be a lot more of these little panels?
1609//
1610// TODO -- currently, this does not patch the deadtime for the back "B" detector. it is a single
1611//        value, not a wave see V_WritePerfectDeadTime(filename) for how the perfect (fake) values is written.
1612//
1613//
1614Proc V_PatchDetectorDeadtime(firstFile,lastFile,detStr,deadtimeStr)
1615        Variable firstFile=1,lastFile=100
1616        String detStr = "FL",deadtimeStr="deadTimeWave"
1617
1618        V_fPatchDetectorDeadtime(firstFile,lastFile,detStr,$deadtimeStr)
1619
1620End
1621
1622Proc V_ReadDetectorDeadtime(firstFile,lastFile,detStr)
1623        Variable firstFile=1,lastFile=100
1624        String detStr = "FL"
1625       
1626        V_fReadDetectorDeadtime(firstFile,lastFile,detStr)
1627       
1628End
1629
1630// simple utility to patch the detector deadtime in the file headers
1631// lo is the first file number
1632// hi is the last file number (inclusive)
1633//
1634Function V_fPatchDetectorDeadtime(lo,hi,detStr,deadtimeW)
1635        Variable lo,hi
1636        String detStr
1637        Wave deadtimeW
1638       
1639        Variable ii
1640        String fname
1641       
1642        // check the dimensions of the deadtimeW/N=48
1643        if (DimSize(deadtimeW, 0) != 48 )
1644                Abort "dead time wave is not of proper dimension (48)"
1645        endif
1646       
1647        //loop over all files
1648        for(ii=lo;ii<=hi;ii+=1)
1649                fname = V_FindFileFromRunNumber(ii)
1650                if(strlen(fname) != 0)
1651                        V_writeDetector_deadtime(fname,detStr,deadtimeW)                       
1652                else
1653                        printf "run number %d not found\r",ii
1654                endif
1655        endfor
1656       
1657        return(0)
1658End
1659
1660// simple utility to read the detector deadtime stored in the file header
1661Function V_fReadDetectorDeadtime(lo,hi,detStr)
1662        Variable lo,hi
1663        String detStr
1664       
1665        String fname
1666        Variable ii
1667       
1668        for(ii=lo;ii<=hi;ii+=1)
1669                fname = V_FindFileFromRunNumber(ii)
1670                if(strlen(fname) != 0)
1671                        Wave deadtimeW = V_getDetector_deadtime(fname,detStr)
1672                        Duplicate/O deadTimeW root:Packages:NIST:VSANS:Globals:Patch:deadtimeWave
1673//                      printf "File %d:  Detector Dead time (s) = %g\r",ii,deadtime
1674                else
1675                        printf "run number %d not found\r",ii
1676                endif
1677        endfor
1678       
1679        return(0)
1680End
1681
1682
1683
1684Proc V_PatchDetectorDeadtimePanel()
1685        DoWindow/F DeadtimePanel
1686        if(V_flag==0)
1687       
1688                NewDataFolder/O/S root:Packages:NIST:VSANS:Globals:Patch
1689
1690                Make/O/D/N=48 deadTimeWave
1691                Variable/G gFileNum_Lo,gFileNum_Hi
1692               
1693                SetDataFolder root:
1694               
1695                Execute "V_DeadtimePatchPanel()"
1696        endif
1697End
1698
1699
1700// TODO:
1701// x- add method for generating "perfect" dead time to write
1702// x- check deadtime wave dimension before writing (check for bad paste operation)
1703// -- load from file? different ways to import?
1704// -- Dead time constants for "B" are different, and not handled here (yet)
1705// -- add help button/file
1706// -- add done button
1707// -- adjust after user testing
1708//
1709Proc V_DeadtimePatchPanel() : Panel
1710        PauseUpdate; Silent 1           // building window...
1711
1712
1713        NewPanel /W=(600,400,1000,1000)/N=DeadtimePanel /K=1
1714//      ShowTools/A
1715        ModifyPanel cbRGB=(16266,47753,2552,23355)
1716
1717        SetDrawLayer UserBack
1718        DrawText 85,99,"Current Values"
1719        DrawText 21,258,"Write to all files (inlcusive)"
1720        SetDrawEnv fsize= 14,fstyle= 1
1721        DrawText 209,30,"Dead Time Constants"
1722        DrawText 20,133,"Run Number(s)"
1723       
1724        PopupMenu popup_0,pos={20,40},size={109,20},title="Detector Panel"
1725        PopupMenu popup_0,mode=1,popvalue="FL",value= #"\"FL;FR;FT;FB;ML;MR;MT;MB;\""
1726       
1727        Button button0,pos={20,81},size={50.00,20.00},proc=V_ReadDTButtonProc,title="Read"
1728        Button button0_1,pos={20,220},size={50.00,20.00},proc=V_WriteDTButtonProc,title="Write"
1729        Button button0_2,pos={18.00,336.00},size={140.00,20.00},proc=V_GeneratePerfDTButton,title="Perfect Dead Time"
1730        Button button0_3,pos={18.00,370.00},size={140.00,20.00},proc=V_LoadCSVDTButton,title="Load Dead Time CSV"
1731        Button button0_4,pos={18.00,400.00},size={140.00,20.00},proc=V_WriteCSVDTButton,title="Write Dead Time CSV"
1732       
1733        SetVariable setvar0,pos={20,141},size={100.00,14.00},title="first"
1734        SetVariable setvar0,value= root:Packages:NIST:VSANS:Globals:Patch:gFileNum_Lo
1735        SetVariable setvar1,pos={20.00,167},size={100.00,14.00},title="last"
1736        SetVariable setvar1,value= root:Packages:NIST:VSANS:Globals:Patch:gFileNum_Hi
1737
1738
1739// display the wave     
1740        Edit/W=(180,40,380,550)/HOST=#  root:Packages:NIST:VSANS:Globals:Patch:deadTimeWave
1741        ModifyTable width(Point)=40
1742        ModifyTable width(root:Packages:NIST:VSANS:Globals:Patch:deadTimeWave)=120
1743        RenameWindow #,T0
1744        SetActiveSubwindow ##
1745
1746       
1747EndMacro
1748
1749
1750Function V_LoadCSVDTButton(ba) : ButtonControl
1751        STRUCT WMButtonAction &ba
1752
1753        switch( ba.eventCode )
1754                case 2: // mouse up
1755                        // click code here
1756
1757                        LoadWave/J/A/D/O/W/E=1/K=0                              //will prompt for the file, auto name
1758                       
1759                        break
1760                case -1: // control being killed
1761                        break
1762        endswitch
1763
1764        return 0
1765End
1766
1767//TODO
1768// -- currently this skips detector "B", since its dead time is not like the tubes
1769// -- fails miserably if the deadtime_** waves don't exist
1770// -- the writing may take a long time. Warn the user.
1771// -- if the data files are not "cleaned up", re-reading will pick up the rawVSANS copy and it
1772//    will look like nothing was written
1773//
1774// writes the entire content of the CSV file (all 8 panels) to each detector entry in each data file
1775// as specified by the run number range
1776//
1777Function V_WriteCSVDTButton(ba) : ButtonControl
1778        STRUCT WMButtonAction &ba
1779
1780        Variable ii
1781        String detStr
1782       
1783        switch( ba.eventCode )
1784                case 2: // mouse up
1785                        // click code here
1786                       
1787//                      ControlInfo popup_0
1788//                      String detStr = S_Value
1789                        ControlInfo setvar0
1790                        Variable lo=V_Value
1791                        ControlInfo setvar1
1792                        Variable hi=V_Value
1793                        Wave deadTimeW = root:Packages:NIST:VSANS:Globals:Patch:deadTimeWave
1794                       
1795                        for(ii=0;ii<ItemsInList(ksDetectorListNoB);ii+=1)
1796                                detStr = StringFromList(ii, ksDetectorListNoB, ";")
1797                                Wave tmpW = $("root:deadtime_"+detStr)
1798                                deadTimeW = tmpW
1799                                V_fPatchDetectorDeadtime(lo,hi,detStr,deadtimeW)
1800                        endfor
1801                       
1802                        break
1803                case -1: // control being killed
1804                        break
1805        endswitch
1806
1807        // TODO
1808        // -- clear out the data folders (from lo to hi?)
1809//
1810// root:Packages:NIST:VSANS:RawVSANS:sans1301:
1811        for(ii=lo;ii<=hi;ii+=1)
1812                KillDataFolder/Z $("root:Packages:NIST:VSANS:RawVSANS:sans"+num2istr(ii))
1813        endfor
1814        return 0
1815End
1816
1817
1818Function V_GeneratePerfDTButton(ba) : ButtonControl
1819        STRUCT WMButtonAction &ba
1820
1821        switch( ba.eventCode )
1822                case 2: // mouse up
1823                        // click code here
1824
1825                        WAVE deadTimeWave = root:Packages:NIST:VSANS:Globals:Patch:deadTimeWave
1826                        ControlInfo popup_0
1827                        strswitch(S_Value)
1828                                case "FR":
1829                                case "FL":
1830                                case "MR":
1831                                case "ML":
1832                                case "FT":
1833                                case "FB":
1834                                case "MT":
1835                                case "MB":
1836                                        deadTimeWave = 1e-18
1837
1838                                        break
1839                                default:
1840                                        Print "Det type not found: V_GeneratePerfDTButton()"
1841                        endswitch
1842                       
1843                        break
1844                case -1: // control being killed
1845                        break
1846        endswitch
1847
1848        return 0
1849End
1850
1851
1852
1853
1854Function V_ReadDTButtonProc(ba) : ButtonControl
1855        STRUCT WMButtonAction &ba
1856
1857        switch( ba.eventCode )
1858                case 2: // mouse up
1859                        // click code here
1860                       
1861                        ControlInfo popup_0
1862                        String detStr = S_Value
1863                        ControlInfo setvar0
1864                        Variable lo=V_Value
1865                        Variable hi=lo
1866                       
1867                        V_fReadDetectorDeadtime(lo,hi,detStr)
1868                       
1869                        break
1870                case -1: // control being killed
1871                        break
1872        endswitch
1873
1874        return 0
1875End
1876
1877Function V_WriteDTButtonProc(ba) : ButtonControl
1878        STRUCT WMButtonAction &ba
1879
1880        switch( ba.eventCode )
1881                case 2: // mouse up
1882                        // click code here
1883                       
1884                        ControlInfo popup_0
1885                        String detStr = S_Value
1886                        ControlInfo setvar0
1887                        Variable lo=V_Value
1888                        ControlInfo setvar1
1889                        Variable hi=V_Value
1890                        Wave deadTimeW = root:Packages:NIST:VSANS:Globals:Patch:deadTimeWave
1891                       
1892                        V_fPatchDetectorDeadtime(lo,hi,detStr,deadtimeW)
1893                       
1894                        break
1895                case -1: // control being killed
1896                        break
1897        endswitch
1898
1899        return 0
1900End
1901
1902//////////////////////////////////////////////////////////////////////////////////////////////////
1903//////////////////////////////////////////////////////////////////////////////////////////////////
1904// this is a block to patch CALIBRATION waves to the file headers, and can patch multiple files
1905//
1906// uses a simple panel to show what the table of values is.
1907// "read" will read only the first run number contents.
1908//
1909// TODO -- need to clear out the contents from RawVSANS, or else re-reading to check the values
1910//        will read locally, and it will look like nothing was written. Executing "save" will also
1911//        trigger a cleanout.
1912//
1913// TODO -- link this to a panel somewhere - a button? menu item? will there be a lot more of these little panels?
1914//
1915// TODO -- currently this does not handle the back detector "B". see V_WritePerfectSpatialCalib(filename)
1916//         for how fake data is written to the files
1917//
1918// TODO -- verify that the calibration waves are not transposed
1919//
1920Proc V_PatchDetectorCalibration(firstFile,lastFile,detStr,calibStr)
1921        Variable firstFile=1,lastFile=100
1922        String detStr = "FL",calibStr="calibrationWave"
1923
1924        V_fPatchDetectorCalibration(firstFile,lastFile,detStr,$calibStr)
1925
1926End
1927
1928Proc V_ReadDetectorCalibration(firstFile,lastFile,detStr)
1929        Variable firstFile=1,lastFile=100
1930        String detStr = "FL"
1931       
1932        V_fReadDetectorCalibration(firstFile,lastFile,detStr)
1933End
1934
1935// simple utility to patch the detector calibration wave in the file headers
1936// lo is the first file number
1937// hi is the last file number (inclusive)
1938//
1939Function V_fPatchDetectorCalibration(lo,hi,detStr,calibW)
1940        Variable lo,hi
1941        String detStr
1942        Wave calibW
1943       
1944        Variable ii
1945        String fname
1946       
1947        // check the dimensions of the calibW (3,48)
1948        if (DimSize(calibW, 0) != 3 || DimSize(calibW, 1) != 48 )
1949                Abort "Calibration wave is not of proper dimension (3,48)"
1950        endif
1951       
1952        //loop over all files
1953        for(ii=lo;ii<=hi;ii+=1)
1954                fname = V_FindFileFromRunNumber(ii)
1955                if(strlen(fname) != 0)
1956                        V_writeDetTube_spatialCalib(fname,detStr,calibW)                       
1957                else
1958                        printf "run number %d not found\r",ii
1959                endif
1960        endfor
1961       
1962        return(0)
1963End
1964
1965// simple utility to read the detector deadtime stored in the file header
1966Function V_fReadDetectorCalibration(lo,hi,detStr)
1967        Variable lo,hi
1968        String detStr
1969       
1970        String fname
1971        Variable ii
1972       
1973        for(ii=lo;ii<=hi;ii+=1)
1974                fname = V_FindFileFromRunNumber(ii)
1975                if(strlen(fname) != 0)
1976                        Wave calibW = V_getDetTube_spatialCalib(fname,detStr)
1977                        Duplicate/O calibW root:Packages:NIST:VSANS:Globals:Patch:calibrationWave
1978                else
1979                        printf "run number %d not found\r",ii
1980                endif
1981        endfor
1982       
1983        return(0)
1984End
1985
1986
1987Proc V_PatchDetectorCalibrationPanel()
1988        DoWindow/F CalibrationPanel
1989        if(V_flag==0)
1990       
1991                NewDataFolder/O/S root:Packages:NIST:VSANS:Globals:Patch
1992
1993                Make/O/D/N=(3,48) calibrationWave
1994               
1995                Variable/G gFileNum_Lo,gFileNum_Hi
1996                SetDataFolder root:
1997               
1998                Execute "V_CalibrationPatchPanel()"
1999        endif
2000End
2001
2002
2003//
2004// TODO:
2005// x- add method for generating "perfect" calibration to write
2006// x- check Nx3 dimension before writing (check for bad paste operation)
2007// -- load from file? different ways to import?
2008// -- calibration constants for "B" are different, and not handled here (yet)
2009// -- add help button/file
2010// -- add done button
2011// -- adjust after user testing
2012//
2013Proc V_CalibrationPatchPanel() : Panel
2014        PauseUpdate; Silent 1           // building window...
2015
2016
2017        NewPanel /W=(600,400,1200,1000)/N=CalibrationPanel /K=1
2018//      ShowTools/A
2019        ModifyPanel cbRGB=(16266,47753,2552,23355)
2020
2021        SetDrawLayer UserBack
2022        DrawText 85,99,"Current Values"
2023        DrawText 21,258,"Write to all files (inlcusive)"
2024        SetDrawEnv fsize= 14,fstyle= 1
2025        DrawText 227,28,"Quadratic Calibration Constants per Tube"
2026        DrawText 20,133,"Run Number(s)"
2027               
2028        PopupMenu popup_0,pos={20,40},size={109,20},title="Detector Panel"
2029        PopupMenu popup_0,mode=1,popvalue="FL",value= #"\"FL;FR;FT;FB;ML;MR;MT;MB;\""
2030       
2031        Button button0,pos={20,81},size={50.00,20.00},proc=V_ReadCalibButtonProc,title="Read"
2032        Button button0_1,pos={20,220},size={50.00,20.00},proc=V_WriteCalibButtonProc,title="Write"
2033        Button button0_2,pos={18.00,336.00},size={140.00,20.00},proc=V_GeneratePerfCalibButton,title="Perfect Calibration"
2034        Button button0_3,pos={18.00,370.00},size={140.00,20.00},proc=V_LoadCSVCalibButton,title="Load Calibration CSV"
2035        Button button0_4,pos={18.00,400.00},size={140.00,20.00},proc=V_WriteCSVCalibButton,title="Write Calibration CSV"
2036               
2037        SetVariable setvar0,pos={20,141},size={100.00,14.00},title="first"
2038        SetVariable setvar0,value= root:Packages:NIST:VSANS:Globals:Patch:gFileNum_Lo
2039        SetVariable setvar1,pos={20.00,167},size={100.00,14.00},title="last"
2040        SetVariable setvar1,value= root:Packages:NIST:VSANS:Globals:Patch:gFileNum_Hi
2041
2042
2043// display the wave     
2044        Edit/W=(180,40,580,550)/HOST=#  root:Packages:NIST:VSANS:Globals:Patch:calibrationWave
2045        ModifyTable width(Point)=40
2046        ModifyTable width(root:Packages:NIST:VSANS:Globals:Patch:calibrationWave)=110
2047        // the elements() command transposes the view in the table, but does not transpose the wave
2048        ModifyTable elements(root:Packages:NIST:VSANS:Globals:Patch:calibrationWave) = (-3, -2)
2049        RenameWindow #,T0
2050        SetActiveSubwindow ##
2051
2052       
2053EndMacro
2054
2055
2056Function V_LoadCSVCalibButton(ba) : ButtonControl
2057        STRUCT WMButtonAction &ba
2058
2059        switch( ba.eventCode )
2060                case 2: // mouse up
2061                        // click code here
2062
2063                        LoadWave/J/A/D/O/W/E=1/K=0                              //will prompt for the file, auto name
2064                       
2065                        break
2066                case -1: // control being killed
2067                        break
2068        endswitch
2069
2070        return 0
2071End
2072
2073//TODO
2074// -- currently this skips detector "B", since its calibration is not like the tubes
2075// -- fails miserably if the a,b,c_** waves don't exist
2076// -- the writing may take a long time. Warn the user.
2077// -- if the data files are not "cleaned up", re-reading will pick up the rawVSANS copy and it
2078//    will look like nothing was written
2079//
2080// writes the entire content of the CSV file (all 8 panels) to each detector entry in each data file
2081// as specified by the run number range
2082//
2083Function V_WriteCSVCalibButton(ba) : ButtonControl
2084        STRUCT WMButtonAction &ba
2085
2086        Variable ii
2087        String detStr
2088       
2089        switch( ba.eventCode )
2090                case 2: // mouse up
2091                        // click code here
2092                       
2093//                      ControlInfo popup_0
2094//                      String detStr = S_Value
2095                        ControlInfo setvar0
2096                        Variable lo=V_Value
2097                        ControlInfo setvar1
2098                        Variable hi=V_Value
2099                        WAVE calibrationWave = root:Packages:NIST:VSANS:Globals:Patch:calibrationWave
2100                       
2101                        for(ii=0;ii<ItemsInList(ksDetectorListNoB);ii+=1)
2102                                detStr = StringFromList(ii, ksDetectorListNoB, ";")
2103                                Wave tmp_a = $("root:a_"+detStr)
2104                                Wave tmp_b = $("root:b_"+detStr)
2105                                Wave tmp_c = $("root:c_"+detStr)
2106                                calibrationWave[0][] = tmp_a[q]
2107                                calibrationWave[1][] = tmp_b[q]
2108                                calibrationWave[2][] = tmp_c[q]
2109                                V_fPatchDetectorCalibration(lo,hi,detStr,calibrationWave)
2110                        endfor
2111                       
2112                        break
2113                case -1: // control being killed
2114                        break
2115        endswitch
2116
2117        // TODO
2118        // -- clear out the data folders (from lo to hi?)
2119//
2120// root:Packages:NIST:VSANS:RawVSANS:sans1301:
2121        for(ii=lo;ii<=hi;ii+=1)
2122                KillDataFolder/Z $("root:Packages:NIST:VSANS:RawVSANS:sans"+num2istr(ii))
2123        endfor
2124        return 0
2125End
2126
2127
2128
2129//      // and for the back detector "B"
2130//      Make/O/D/N=3 tmpCalib
2131//      tmpCalib[0] = 1
2132//      tmpCalib[1] = 1
2133//      tmpcalib[2] = 10000
2134//      V_writeDet_cal_x(filename,"B",tmpCalib)
2135//      V_writeDet_cal_y(filename,"B",tmpCalib)
2136//
2137// "Perfect" values here are from Phil (2/2018)
2138//
2139Function V_GeneratePerfCalibButton(ba) : ButtonControl
2140        STRUCT WMButtonAction &ba
2141
2142        switch( ba.eventCode )
2143                case 2: // mouse up
2144                        // click code here
2145
2146                        WAVE calibrationWave = root:Packages:NIST:VSANS:Globals:Patch:calibrationWave
2147                        ControlInfo popup_0
2148                        strswitch(S_Value)
2149                                case "FR":
2150                                case "FL":
2151                                case "MR":
2152                                case "ML":
2153                                        //      // for the "tall" L/R banks
2154                                        calibrationWave[0][] = -521
2155                                        calibrationWave[1][] = 8.14
2156                                        calibrationWave[2][] = 0
2157                                        break
2158                                case "FT":
2159                                case "FB":
2160                                case "MT":
2161                                case "MB":
2162                                        //      // for the "short" T/B banks
2163                                        calibrationWave[0][] = -266
2164                                        calibrationWave[1][] = 4.16
2165                                        calibrationWave[2][] = 0
2166
2167                                        break
2168                                default:
2169                                        Print "Det type not found: V_GeneratePerfCalibButton()"
2170                        endswitch
2171
2172
2173                       
2174                        break
2175                case -1: // control being killed
2176                        break
2177        endswitch
2178
2179        return 0
2180End
2181
2182
2183Function V_ReadCalibButtonProc(ba) : ButtonControl
2184        STRUCT WMButtonAction &ba
2185
2186        switch( ba.eventCode )
2187                case 2: // mouse up
2188                        // click code here
2189                       
2190                        ControlInfo popup_0
2191                        String detStr = S_Value
2192                        ControlInfo setvar0
2193                        Variable lo=V_Value
2194                        Variable hi=lo
2195                       
2196                        V_fReadDetectorCalibration(lo,hi,detStr)
2197                       
2198                        break
2199                case -1: // control being killed
2200                        break
2201        endswitch
2202
2203        return 0
2204End
2205
2206Function V_WriteCalibButtonProc(ba) : ButtonControl
2207        STRUCT WMButtonAction &ba
2208
2209        switch( ba.eventCode )
2210                case 2: // mouse up
2211                        // click code here
2212                       
2213                        ControlInfo popup_0
2214                        String detStr = S_Value
2215                        ControlInfo setvar0
2216                        Variable lo=V_Value
2217                        ControlInfo setvar1
2218                        Variable hi=V_Value
2219                        Wave calibW = root:Packages:NIST:VSANS:Globals:Patch:calibrationWave
2220                       
2221                        V_fPatchDetectorCalibration(lo,hi,detStr,calibW)
2222                       
2223                        break
2224                case -1: // control being killed
2225                        break
2226        endswitch
2227
2228        return 0
2229End
2230
2231
2232
2233//////////////////////////////////////////////////////////////////////////////////////////////////
2234//////////////////////////////////////////////////////////////////////////////////////////////////
2235
2236
2237
2238////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2239////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2240///////////////
2241//
2242// this is a block to patch beam centers to the file headers
2243// it will patch the headers for all 9 detectors
2244// and can patch multiple files
2245//
2246// uses a simple panel to show what the table of values is.
2247// "read" will read only the first run number contents. this is the "good" set of XY
2248//  that you want to write out to other files.
2249//
2250// TODO -- need to clear out the contents from RawVSANS, or else re-reading to check the values
2251//        will read locally, and it will look like nothing was written. Executing "save" will also
2252//        trigger a cleanout.
2253//
2254// TODO - link this to a panel somewhere - a button? menu item? will there be a lot more of these little panels?
2255//
2256Proc V_PatchDet_xyCenters(firstFile,lastFile)
2257        Variable firstFile=1,lastFile=100
2258
2259        V_fPatchDet_xyCenters(firstFile,lastFile)
2260
2261End
2262
2263Proc V_ReadDet_xyCenters(firstFile,lastFile)
2264        Variable firstFile=1,lastFile=100
2265
2266       
2267        V_fReadDet_xyCenters(firstFile,lastFile)
2268End
2269
2270// simple utility to patch the xy center in the file headers
2271// lo is the first file number
2272// hi is the last file number (inclusive)
2273//
2274//
2275//              added in May 2019 -- kill the same numbered files from RawVSANS to force a re-read since the XY
2276//  has been changed
2277Function V_fPatchDet_xyCenters(lo,hi)
2278        Variable lo,hi
2279
2280       
2281        Variable ii,jj
2282        String fname,detStr
2283       
2284        Wave xCtr_cm = root:Packages:NIST:VSANS:Globals:Patch:xCtr_cm
2285        Wave yCtr_cm = root:Packages:NIST:VSANS:Globals:Patch:yCtr_cm
2286        Wave/T panelW = root:Packages:NIST:VSANS:Globals:Patch:panelW
2287       
2288        // check the dimensions of the waves (9)
2289        if (DimSize(xCtr_cm, 0) != 9 || DimSize(yCtr_cm, 0) != 9 || DimSize(panelW, 0) != 9)
2290                Abort "waves are not of proper dimension (9)"
2291        endif
2292       
2293        //loop over all files
2294        for(jj=lo;jj<=hi;jj+=1)
2295                fname = V_FindFileFromRunNumber(jj)
2296                if(strlen(fname) != 0)
2297               
2298                        for(ii=0;ii<ItemsInList(ksDetectorListAll);ii+=1)
2299                                detStr = panelW[ii]
2300                                V_writeDet_beam_center_x(fname,detStr,xCtr_cm[ii])
2301                                V_writeDet_beam_center_y(fname,detStr,yCtr_cm[ii])             
2302                        endfor 
2303               
2304                // then delete the file from RawVSANS
2305                        V_KillNamedDataFolder(fname)
2306                       
2307                else
2308                        printf "run number %d not found\r",jj
2309                endif
2310        endfor
2311       
2312        return(0)
2313End
2314
2315// simple utility to read the detector xy centers stored in the file header
2316Function V_fReadDet_xyCenters(lo,hi)
2317        Variable lo,hi
2318
2319       
2320        String fname,detStr
2321        Variable ii,jj
2322       
2323        Wave xCtr_cm = root:Packages:NIST:VSANS:Globals:Patch:xCtr_cm
2324        Wave yCtr_cm = root:Packages:NIST:VSANS:Globals:Patch:yCtr_cm
2325        Wave/T panelW = root:Packages:NIST:VSANS:Globals:Patch:panelW
2326       
2327        for(jj=lo;jj<=hi;jj+=1)
2328                fname = V_FindFileFromRunNumber(jj)
2329                if(strlen(fname) != 0)
2330               
2331                        for(ii=0;ii<ItemsInList(ksDetectorListAll);ii+=1)
2332                                detStr = StringFromList(ii, ksDetectorListAll, ";")
2333                                panelW[ii] = detStr
2334                                xCtr_cm[ii] = V_getDet_beam_center_x(fname,detStr)              //these values are in cm, not pixels
2335                                yCtr_cm[ii] = V_getDet_beam_center_y(fname,detStr)
2336                        endfor
2337               
2338               
2339                else
2340                        printf "run number %d not found\r",jj
2341                endif
2342               
2343        endfor
2344
2345       
2346        return(0)
2347End
2348
2349
2350
2351Proc V_PatchDet_xyCenters_Panel()
2352        DoWindow/F Patch_XY_Panel
2353        if(V_flag==0)
2354       
2355                NewDataFolder/O/S root:Packages:NIST:VSANS:Globals:Patch
2356
2357                Make/O/D/N=9 xCtr_cm,yCtr_cm
2358                Make/O/T/N=9 panelW
2359               
2360                PanelW = {"FL","FR","FT","FB","ML","MR","MT","MB","B"}
2361               
2362                Variable/G gFileNum_Lo,gFileNum_Hi
2363               
2364                SetDataFolder root:
2365               
2366                Execute "V_Patch_xyCtr_Panel()"
2367        endif
2368End
2369
2370
2371// TODO:
2372// -- add method to read (import) from beam center panel
2373// x- check wave dimensions before writing (check for bad paste operation)
2374// -- load from file? different ways to import?
2375// -- add help button/file
2376// -- add done button
2377// -- adjust after user testing
2378//
2379Proc V_Patch_xyCtr_Panel() : Panel
2380        PauseUpdate; Silent 1           // building window...
2381
2382
2383        NewPanel /W=(600,400,1150,800)/N=Patch_XY_Panel /K=1
2384//      ShowTools/A
2385       
2386        ModifyPanel cbRGB=(16266,47753,2552,23355)
2387
2388        SetDrawLayer UserBack
2389        DrawText 85,99,"Current Values"
2390        DrawText 21,258,"Write to all files (inlcusive)"
2391        SetDrawEnv fsize= 14,fstyle= 1
2392        DrawText 262,30,"Beam Center [cm]"
2393        DrawText 20,133,"Run Number(s)"
2394       
2395        Button button0,pos={20,81},size={50.00,20.00},proc=V_ReadXYButtonProc,title="Read"
2396        Button button0_1,pos={20,220},size={50.00,20.00},proc=V_WriteXYButtonProc,title="Write"
2397        SetVariable setvar0,pos={20,141},size={100.00,14.00},title="first"
2398        SetVariable setvar0,value= root:Packages:NIST:VSANS:Globals:Patch:gFileNum_Lo
2399        SetVariable setvar1,pos={20.00,167},size={100.00,14.00},title="last"
2400        SetVariable setvar1,value= root:Packages:NIST:VSANS:Globals:Patch:gFileNum_Hi
2401
2402       
2403        SetDataFolder root:Packages:NIST:VSANS:Globals:Patch
2404// display the wave     
2405        Edit/W=(180,40,500,370)/HOST=#  panelW,xCtr_cm,yCtr_cm
2406        ModifyTable width(Point)=0
2407        ModifyTable width(panelW)=80
2408        ModifyTable width(xCtr_cm)=100
2409        ModifyTable width(yCtr_cm)=100
2410        RenameWindow #,T0
2411        SetActiveSubwindow ##
2412
2413        SetDataFolder root:
2414       
2415EndMacro
2416
2417
2418Function V_ReadXYButtonProc(ba) : ButtonControl
2419        STRUCT WMButtonAction &ba
2420
2421        switch( ba.eventCode )
2422                case 2: // mouse up
2423                        // click code here
2424                       
2425//                      ControlInfo popup_0
2426//                      String detStr = S_Value
2427                        ControlInfo setvar0
2428                        Variable lo=V_Value
2429                        Variable hi=lo
2430                       
2431                        V_fReadDet_xyCenters(lo,hi)
2432                       
2433                        break
2434                case -1: // control being killed
2435                        break
2436        endswitch
2437
2438        return 0
2439End
2440
2441Function V_WriteXYButtonProc(ba) : ButtonControl
2442        STRUCT WMButtonAction &ba
2443
2444        switch( ba.eventCode )
2445                case 2: // mouse up
2446                        // click code here
2447                       
2448//                      ControlInfo popup_0
2449//                      String detStr = S_Value
2450                        ControlInfo setvar0
2451                        Variable lo=V_Value
2452                        ControlInfo setvar1
2453                        Variable hi=V_Value
2454//                      Wave deadTimeW = root:Packages:NIST:VSANS:Globals:Patch:deadTimeWave
2455
2456// this function will write the new centers to the file and then delete the file from
2457// RawVSANS to force a re-read of the data                     
2458                        V_fPatchDet_xyCenters(lo,hi)
2459
2460                        break
2461                case -1: // control being killed
2462                        break
2463        endswitch
2464
2465        return 0
2466End
2467
2468//////////////////////////////////////////////////////////////////////////////////////////////////
2469//////////////////////////////////////////////////////////////////////////////////////////////////
2470
2471
2472Proc V_PatchDet_Offset(lo,hi)
2473        Variable lo,hi
2474       
2475        V_fPatchDet_Offset(lo,hi)
2476End
2477
2478Proc V_MarkLeftRightFlip_Done(lo,hi)
2479        Variable lo,hi
2480       
2481        V_fWriteFlipState(lo,hi,1)      // value == 1 means flip done
2482End
2483
2484Proc V_MarkLeftRightFlip_Not_Done(lo,hi)
2485        Variable lo,hi
2486       
2487        V_fWriteFlipState(lo,hi,-999999)        // value == -999999 means flip not done
2488End
2489
2490
2491Proc V_Patch_GroupID_catTable()
2492        V_fPatch_GroupID_catTable()
2493end
2494
2495Proc V_Patch_Purpose_catTable()
2496        V_fPatch_Purpose_catTable()
2497end
2498
2499Proc V_Patch_Intent_catTable()
2500        V_fPatch_Intent_catTable()
2501end
2502
2503Proc V_PatchDet_Gap(lo,hi)
2504        Variable lo,hi
2505       
2506        V_fPatchDet_Gap(lo,hi)
2507End
2508
2509Proc V_ReadDet_Gap(lo,hi)
2510        Variable lo,hi
2511       
2512        V_fReadDet_Gap(lo,hi)
2513End
2514
2515Proc V_PatchDet_Distance(lo,hi,dist_f,dist_m,dist_b)
2516        Variable lo,hi,dist_f=400,dist_m=1900,dist_b=2200
2517       
2518        V_fPatchDet_distance(lo,hi,dist_f,dist_m,dist_b)
2519End
2520
2521Proc V_Patch_Back_Detector(lo,hi)
2522        Variable lo,hi
2523       
2524        V_fPatch_BackDetector(lo,hi)
2525End
2526
2527Proc V_Patch_Back_XYPixelSize(lo,hi)
2528        Variable lo,hi
2529       
2530        V_fPatch_BackDetectorPixel(lo,hi)
2531end
2532
2533Proc V_Patch_XYPixelSize(lo,hi)
2534        Variable lo,hi
2535       
2536        V_fPatch_XYPixelSize(lo,hi)
2537End
2538
2539// simple utility to patch the offset values in the file headers
2540//
2541// Swaps only the L/R detector values
2542// lo is the first file number
2543// hi is the last file number (inclusive)
2544//
2545//              V_getLeftRightFlipDone(fname)
2546//
2547//
2548// updated the function to check for the "already done" flag
2549// - if already done, report this and do nothing.
2550// - if not done, do the flip and set the flag
2551//
2552Function V_fPatchDet_Offset(lo,hi)
2553        Variable lo,hi
2554
2555       
2556        Variable ii,jj,flipDone=0
2557        String fname,detStr
2558       
2559        Variable offset_ML,offset_MR,offset_FL,offset_FR
2560
2561       
2562        //loop over all files
2563        for(jj=lo;jj<=hi;jj+=1)
2564                fname = V_FindFileFromRunNumber(jj)
2565                if(strlen(fname) != 0)
2566               
2567                        flipDone = V_getLeftRightFlipDone(fname)
2568                        if(flipDone == 1)
2569                                printf "run number %d already flipped - nothing done\r",jj
2570                        else
2571                                offset_FL = V_getDet_LateralOffset(fname,"FL")
2572                                offset_FR = V_getDet_LateralOffset(fname,"FR")
2573       
2574                                offset_ML = V_getDet_LateralOffset(fname,"ML")
2575                                offset_MR = V_getDet_LateralOffset(fname,"MR")
2576                       
2577                        // swap L/R offset values
2578                                V_WriteDet_LateralOffset(fname,"FL",-offset_FR)
2579                                V_WriteDet_LateralOffset(fname,"FR",-offset_FL)
2580                               
2581                                V_WriteDet_LateralOffset(fname,"ML",-offset_MR)
2582                                V_WriteDet_LateralOffset(fname,"MR",-offset_ML)
2583                       
2584                        // set the flag
2585                                V_writeLeftRightFlipDone(fname,1)               // value == 1 means the flip was done
2586                                Print fname
2587                                Print "swapped FL, FR = ",-offset_FR,-offset_FL
2588                                Print "swapped ML, MR = ",-offset_MR,-offset_ML
2589                       
2590                        endif
2591               
2592                else
2593                        printf "run number %d not found\r",jj
2594                endif
2595               
2596        endfor
2597       
2598        return(0)
2599End
2600
2601//  utility to reset the flip state in the file headers
2602//
2603// lo is the first file number
2604// hi is the last file number (inclusive)
2605//
2606// setting value == 1 means done
2607// setting value == -999999 means not done (mimics a missing /entry)
2608//
2609Function V_fWriteFlipState(lo,hi,val)
2610        Variable lo,hi,val
2611
2612       
2613        Variable ii,jj,flipDone=0
2614        String fname,detStr
2615       
2616        Variable offset_ML,offset_MR,offset_FL,offset_FR
2617
2618        //loop over all files
2619        for(jj=lo;jj<=hi;jj+=1)
2620                fname = V_FindFileFromRunNumber(jj)
2621                if(strlen(fname) != 0)
2622       
2623                // set the flag
2624                        V_writeLeftRightFlipDone(fname,val)             //
2625                        Print fname
2626                        printf "run number %d flag reset to %d\r",jj,val
2627                       
2628                else
2629                        printf "run number %d not found\r",jj
2630                endif
2631               
2632        endfor
2633       
2634        return(0)
2635End
2636
2637
2638
2639// simple utility to read the detector offset stored in the file header
2640Function V_fReadDet_Offset(lo,hi)
2641        Variable lo,hi
2642
2643        String fname,detStr
2644        Variable jj
2645        Variable offset_ML,offset_MR,offset_FL,offset_FR
2646       
2647        for(jj=lo;jj<=hi;jj+=1)
2648                fname = V_FindFileFromRunNumber(jj)
2649                if(strlen(fname) != 0)
2650               
2651                        offset_FL = V_getDet_LateralOffset(fname,"FL")
2652                        offset_FR = V_getDet_LateralOffset(fname,"FR")
2653
2654                        offset_ML = V_getDet_LateralOffset(fname,"ML")
2655                        offset_MR = V_getDet_LateralOffset(fname,"MR")
2656               
2657                        Print fname
2658                        Print "FL, FR = ",offset_FL,offset_FR
2659                        Print "ML, MR = ",offset_ML,offset_MR
2660               
2661               
2662                else
2663                        printf "run number %d not found\r",jj
2664                endif
2665               
2666        endfor
2667
2668       
2669        return(0)
2670End
2671
2672
2673// patches the group_ID, based on whatever is in the catTable
2674//
2675Function V_fPatch_GroupID_catTable()
2676        Variable lo,hi
2677
2678       
2679        Variable ii,jj,num
2680       
2681        Wave id = root:Packages:NIST:VSANS:CatVSHeaderInfo:Group_ID
2682        Wave/T fileNameW = root:Packages:NIST:VSANS:CatVSHeaderInfo:Filenames
2683
2684        num = numpnts(id)       
2685        //loop over all files
2686        for(jj=0;jj<num;jj+=1)
2687                Print "update file ",jj,fileNameW[jj]
2688                V_writeSample_GroupID(fileNameW[jj],id[jj])     
2689        endfor
2690       
2691        return(0)
2692End
2693
2694
2695// patches the Purpose, based on whatever is in the catTable
2696//
2697Function V_fPatch_Purpose_catTable()
2698        Variable lo,hi
2699
2700       
2701        Variable ii,jj,num
2702       
2703        Wave/T purpose = root:Packages:NIST:VSANS:CatVSHeaderInfo:Purpose
2704        Wave/T fileNameW = root:Packages:NIST:VSANS:CatVSHeaderInfo:Filenames
2705
2706        num = numpnts(purpose) 
2707        //loop over all files
2708        for(jj=0;jj<num;jj+=1)
2709                Print "update file ",jj,fileNameW[jj]
2710                V_writeReduction_Purpose(fileNameW[jj],purpose[jj])     
2711        endfor
2712       
2713        return(0)
2714End
2715
2716// patches the Intent, based on whatever is in the catTable
2717//
2718Function V_fPatch_Intent_catTable()
2719        Variable lo,hi
2720
2721       
2722        Variable ii,jj,num
2723       
2724        Wave/T intent = root:Packages:NIST:VSANS:CatVSHeaderInfo:Intent
2725        Wave/T fileNameW = root:Packages:NIST:VSANS:CatVSHeaderInfo:Filenames
2726
2727        num = numpnts(intent)   
2728        //loop over all files
2729        for(jj=0;jj<num;jj+=1)
2730                Print "update file ",jj,fileNameW[jj]
2731                V_writeReductionIntent(fileNameW[jj],intent[jj])       
2732        endfor
2733       
2734        return(0)
2735End
2736
2737
2738
2739// simple utility to patch the detector gap values in the file headers
2740//
2741// values are measured values in [mm], not estimated
2742//
2743// lo is the first file number
2744// hi is the last file number (inclusive)
2745//
2746Function V_fPatchDet_Gap(lo,hi)
2747        Variable lo,hi
2748
2749       
2750        Variable ii,jj
2751        String fname,detStr
2752               
2753        //loop over all files
2754        for(jj=lo;jj<=hi;jj+=1)
2755                fname = V_FindFileFromRunNumber(jj)
2756                if(strlen(fname) != 0)
2757               
2758                // write gap values
2759                        V_writeDet_panel_gap(fname,"FL",3.5)
2760                        V_writeDet_panel_gap(fname,"FR",3.5)
2761
2762                        V_writeDet_panel_gap(fname,"FT",3.3)
2763                        V_writeDet_panel_gap(fname,"FB",3.3)
2764
2765                        V_writeDet_panel_gap(fname,"ML",5.9)
2766                        V_writeDet_panel_gap(fname,"MR",5.9)
2767
2768                        V_writeDet_panel_gap(fname,"MT",18.3)
2769                        V_writeDet_panel_gap(fname,"MB",18.3)           
2770               
2771                else
2772                        printf "run number %d not found\r",jj
2773                endif
2774        endfor
2775       
2776        return(0)
2777End
2778
2779// simple utility to read the detector gap values stored in the file header
2780Function V_fReadDet_Gap(lo,hi)
2781        Variable lo,hi
2782
2783        String fname,detStr
2784        Variable jj
2785        Variable gap_FL,gap_FR,gap_FT,gap_FB,gap_ML,gap_MR,gap_MT,gap_MB
2786       
2787        for(jj=lo;jj<=hi;jj+=1)
2788                fname = V_FindFileFromRunNumber(jj)
2789                if(strlen(fname) != 0)
2790               
2791                        gap_FL = V_getDet_panel_gap(fname,"FL")
2792                        gap_FR = V_getDet_panel_gap(fname,"FR")
2793                        gap_FT = V_getDet_panel_gap(fname,"FT")
2794                        gap_FB = V_getDet_panel_gap(fname,"FB")
2795
2796                        gap_ML = V_getDet_panel_gap(fname,"ML")
2797                        gap_MR = V_getDet_panel_gap(fname,"MR")
2798                        gap_MT = V_getDet_panel_gap(fname,"MT")
2799                        gap_MB = V_getDet_panel_gap(fname,"MB")
2800                       
2801                        print fname     
2802                        Print "FL, FR, FT, FB = ",gap_FL,gap_FR,gap_FT,gap_FB
2803                        Print "ML, MR, MT, MB = ",gap_ML,gap_MR,gap_MT,gap_MB
2804               
2805               
2806                else
2807                        printf "run number %d not found\r",jj
2808                endif
2809               
2810        endfor
2811
2812       
2813        return(0)
2814End
2815
2816
2817// simple utility to patch the detector distance values in the file headers
2818//
2819// values are in [cm]
2820//
2821// lo is the first file number
2822// hi is the last file number (inclusive)
2823//
2824Function V_fPatchDet_distance(lo,hi,d_f,d_m,d_b)
2825        Variable lo,hi,d_f,d_m,d_b
2826
2827       
2828        Variable ii,jj
2829        String fname,detStr
2830               
2831        //loop over all files
2832        for(jj=lo;jj<=hi;jj+=1)
2833                fname = V_FindFileFromRunNumber(jj)
2834                if(strlen(fname) != 0)
2835               
2836                // write gap values
2837                        V_writeDet_distance(fname,"FL",d_f)
2838                        V_writeDet_distance(fname,"FR",d_f)
2839                        V_writeDet_distance(fname,"FT",d_f)
2840                        V_writeDet_distance(fname,"FB",d_f)
2841
2842                        V_writeDet_distance(fname,"ML",d_m)
2843                        V_writeDet_distance(fname,"MR",d_m)
2844                        V_writeDet_distance(fname,"MT",d_m)
2845                        V_writeDet_distance(fname,"MB",d_m)             
2846
2847                        V_writeDet_distance(fname,"B",d_b)             
2848               
2849                else
2850                        printf "run number %d not found\r",jj
2851                endif
2852        endfor
2853       
2854        return(0)
2855End
2856
2857
2858//
2859// simple utility to patch all of the values associated with the back detector
2860//
2861// as of Dec 2019, this is not used any longer as these values are all written correctly,
2862// except for patching old data with the XY pixel dimensions (separate macro)
2863//
2864//
2865// lo is the first file number
2866// hi is the last file number (inclusive)
2867//
2868Function V_fPatch_BackDetector(lo,hi)
2869        Variable lo,hi
2870
2871       
2872        Variable ii,jj
2873        String fname,detStr
2874       
2875        detStr = "B"
2876       
2877        Make/O/D/N=3 cal_x,cal_y
2878        cal_x[0] = VCALC_getPixSizeX(detStr)                    // pixel size in VCALC_getPixSizeX(detStr) is [cm]
2879        cal_x[1] = 1
2880        cal_x[2] = 10000
2881        cal_y[0] = VCALC_getPixSizeY(detStr)                    // pixel size in VCALC_getPixSizeX(detStr) is [cm]
2882        cal_y[1] = 1
2883        cal_y[2] = 10000
2884       
2885        Make/O/I/N=(680,1656) tmpData=1
2886       
2887        //loop over all files
2888        for(jj=lo;jj<=hi;jj+=1)
2889                fname = V_FindFileFromRunNumber(jj)
2890                if(strlen(fname) != 0)
2891               
2892                // patch cal_x and cal_y
2893                        V_writeDet_cal_x(fname,detStr,cal_x)
2894                        V_writeDet_cal_y(fname,detStr,cal_y)
2895               
2896                // patch n_pix_x and y
2897                        V_writeDet_pixel_num_x(fname,detStr,680)
2898                        V_writeDet_pixel_num_y(fname,detStr,1656)
2899                       
2900                // patch pixel size x and y [cm]
2901                        V_writeDet_x_pixel_size(fname,detStr,0.034)
2902                        V_writeDet_y_pixel_size(fname,detStr,0.034)
2903                       
2904                // patch dead time
2905                // TODO: enter a proper value here once it's actually measured
2906                        V_writeDetector_deadtime_B(fname,detStr,1e-20)
2907               
2908                // patch fwhm_x and y
2909                // TODO: verify the values once they are measured, and also the UNITS!!! [cm]???
2910                        V_writeDet_pixel_fwhm_x(fname,detStr,0.034)
2911                        V_writeDet_pixel_fwhm_y(fname,detStr,0.034)
2912               
2913                // patch beam center (nominal x,y) [cm] values
2914                        V_writeDet_beam_center_x(fname,detStr,11)
2915                        V_writeDet_beam_center_y(fname,detStr,25)
2916               
2917                // fake data
2918//                      V_writeDetectorData(fname,detStr,tmpData)
2919                       
2920                       
2921                else
2922                        printf "run number %d not found\r",jj
2923                endif
2924        endfor
2925       
2926        KillWaves/Z cal_x,cal_y,tmpData
2927        return(0)
2928End
2929
2930
2931//
2932// simple utility to patch the X and Y Pixel dimensions for the back detector
2933// the cal_x(y) values are what is actually used to calculate the real space distance
2934// and then ultimately the q-values.
2935//
2936// **this updated value for the pixel size is from a measurement of a grid of pinholes
2937// as a mask in front of the detector (done in Sept 2019,  run 43550 - calculations
2938// done in Dec 2019)
2939//
2940//
2941// lo is the first file number
2942// hi is the last file number (inclusive)
2943//
2944Function V_fPatch_BackDetectorPixel(lo,hi)
2945        Variable lo,hi
2946
2947       
2948        Variable ii,jj
2949        String fname,detStr
2950       
2951        detStr = "B"
2952       
2953        Make/O/D/N=3 cal_x,cal_y
2954        cal_x[0] = 0.03175                      // pixel size in VCALC_getPixSizeX(detStr) is [cm]
2955        cal_x[1] = 1
2956        cal_x[2] = 10000
2957        cal_y[0] = 0.03175              // pixel size in VCALC_getPixSizeX(detStr) is [cm]
2958        cal_y[1] = 1
2959        cal_y[2] = 10000
2960       
2961       
2962        //loop over all files
2963        for(jj=lo;jj<=hi;jj+=1)
2964                fname = V_FindFileFromRunNumber(jj)
2965                if(strlen(fname) != 0)
2966               
2967                // patch cal_x and cal_y
2968                        V_writeDet_cal_x(fname,detStr,cal_x)
2969                        V_writeDet_cal_y(fname,detStr,cal_y)
2970                               
2971                // patch pixel size x and y [cm]
2972                        V_writeDet_x_pixel_size(fname,detStr,0.03175)
2973                        V_writeDet_y_pixel_size(fname,detStr,0.03175)
2974                                       
2975                else
2976                        printf "run number %d not found\r",jj
2977                endif
2978        endfor
2979       
2980        KillWaves/Z cal_x,cal_y
2981        return(0)
2982End
2983
2984
2985
2986//
2987// simple utility to patch all of the pixel sizes
2988// - in the header, the Y size for LR panels was grossly wrong (4 mm)
2989// and all of the values are slightly off from the true values
2990//
2991// data collected after 10/3/18 should not need this patch since the
2992// config.js file was updated
2993//
2994//
2995//
2996// lo is the first file number
2997// hi is the last file number (inclusive)
2998//
2999Function V_fPatch_XYPixelSize(lo,hi)
3000        Variable lo,hi
3001
3002       
3003        Variable ii,jj
3004        String fname,detStr
3005       
3006       
3007        //loop over all files
3008        for(jj=lo;jj<=hi;jj+=1)
3009                fname = V_FindFileFromRunNumber(jj)
3010                if(strlen(fname) != 0)
3011                       
3012                // patch pixel size x and y [cm] L/R panels
3013                        V_writeDet_x_pixel_size(fname,"FL",8.4)
3014                        V_writeDet_y_pixel_size(fname,"FL",8.14)
3015
3016                        V_writeDet_x_pixel_size(fname,"FR",8.4)
3017                        V_writeDet_y_pixel_size(fname,"FR",8.14)                       
3018
3019                        V_writeDet_x_pixel_size(fname,"ML",8.4)
3020                        V_writeDet_y_pixel_size(fname,"ML",8.14)
3021
3022                        V_writeDet_x_pixel_size(fname,"MR",8.4)
3023                        V_writeDet_y_pixel_size(fname,"MR",8.14)
3024                       
3025                // patch pixel size x and y [cm] T/B panels
3026                        V_writeDet_x_pixel_size(fname,"FT",4.16)
3027                        V_writeDet_y_pixel_size(fname,"FT",8.4)
3028
3029                        V_writeDet_x_pixel_size(fname,"FB",4.16)
3030                        V_writeDet_y_pixel_size(fname,"FB",8.4)                 
3031
3032                        V_writeDet_x_pixel_size(fname,"MT",4.16)
3033                        V_writeDet_y_pixel_size(fname,"MT",8.4)
3034
3035                        V_writeDet_x_pixel_size(fname,"MB",4.16)
3036                        V_writeDet_y_pixel_size(fname,"MB",8.4)                 
3037                       
3038                else
3039                        printf "run number %d not found\r",jj
3040                endif
3041        endfor
3042       
3043        return(0)
3044End
3045
3046
3047Proc V_Patch_Guide_SSD_Aperture(lo,hi,numGuideStr,sourceDiam_mm)
3048        Variable lo,hi
3049        String numGuideStr="CONV_BEAMS"
3050        Variable sourceDiam_mm=30
3051       
3052        V_fPatch_Guide_SSD_Aperture(lo,hi,numGuideStr,sourceDiam_mm)
3053End
3054
3055
3056
3057// simple utility to patch all three at once, since they are all linked and typically
3058/// are all incorrectly entered by NICE if the number of guides can't be determined
3059//
3060// Number of guides
3061// source aperture to gate valve distance [cm]
3062// source aperture diameter [mm]
3063//
3064// the source aperture is assumed to be circular and the diameter in mm
3065//
3066// the value for the A1_to_GV is from tabulated values.  (see VC_calcSSD)
3067// This is the Source aperture to Gate Valve distance
3068//
3069//
3070// lo is the first file number
3071// hi is the last file number (inclusive)
3072//
3073Function V_fPatch_Guide_SSD_Aperture(lo,hi,numGuideStr,sourceDiam_mm)
3074        Variable lo,hi
3075        String numGuideStr
3076        Variable sourceDiam_mm
3077
3078       
3079        Variable ii,jj,A1_to_GV
3080        String fname,detStr
3081
3082        strswitch(numGuideStr)
3083                case "CONV_BEAMS":
3084                case "NARROW_SLITS":
3085                case "0":
3086                                A1_to_GV = 2441
3087                        break
3088                case "1":
3089                                A1_to_GV = 2157
3090                        break
3091                case "2":
3092                                A1_to_GV = 1976
3093                        break
3094                case "3":
3095                                A1_to_GV = 1782
3096                        break                   
3097                case "4":
3098                                A1_to_GV = 1582
3099                        break                   
3100                case "5":
3101                                A1_to_GV = 1381
3102                        break                   
3103                case "6":
3104                                A1_to_GV = 1181
3105                        break                   
3106                case "7":
3107                                A1_to_GV = 980
3108                        break                   
3109                case "8":
3110                                A1_to_GV = 780
3111                        break                   
3112                case "9":
3113                                A1_to_GV = 579
3114                        break                   
3115                default:
3116                        Print "Error - using default A1_to_GV value"
3117                        A1_to_GV = 2441
3118        endswitch
3119
3120               
3121        //loop over all files
3122        for(jj=lo;jj<=hi;jj+=1)
3123                fname = V_FindFileFromRunNumber(jj)
3124                if(strlen(fname) != 0)
3125               
3126                // write values
3127                V_writeNumberOfGuides(fname,numGuideStr)
3128
3129                V_writeSourceAp_distance(fname,A1_to_GV)
3130
3131                V_writeSourceAp_shape(fname,"CIRCLE")
3132                V_writeSourceAp_size(fname,num2str(sourceDiam_mm))
3133
3134                else
3135                        printf "run number %d not found\r",jj
3136                endif
3137        endfor
3138       
3139        return(0)
3140End
3141
3142
3143//
3144// pick the carriage, beamstop number, beamstop shape, and beamstop diameter
3145// or height and width
3146Proc V_Patch_BeamStop(lo,hi,carriageStr,bs_num,bsShapeStr,bs_diam,bs_width,bs_height)
3147        Variable lo,hi
3148        String carriageStr="B"
3149        Variable bs_num=2
3150        String bsShapeStr="CIRCLE"
3151        Variable bs_diam=12,bs_width=12,bs_height=300
3152       
3153        V_fPatch_BeamStop(lo,hi,carriageStr,bs_num,bsShapeStr,bs_diam,bs_width,bs_height)
3154End
3155
3156
3157//
3158// lo is the first file number
3159// hi is the last file number (inclusive)
3160//
3161Function V_fPatch_BeamStop(lo,hi,carriageStr,bs_num,bsShapeStr,bs_diam,bs_width,bs_height)
3162        Variable lo,hi
3163        String carriageStr
3164        Variable bs_num
3165        String bsShapeStr
3166        Variable bs_diam,bs_width,bs_height
3167
3168       
3169        Variable ii,jj,A1_to_GV
3170        String fname,detStr
3171
3172               
3173        //loop over all files
3174        for(jj=lo;jj<=hi;jj+=1)
3175                fname = V_FindFileFromRunNumber(jj)
3176                if(strlen(fname) != 0)
3177
3178                        if(cmpstr("F",carriageStr) == 0)
3179                                Print "front carriage has no beamstops"
3180                        endif
3181                       
3182                        if(cmpstr("M",carriageStr) == 0)
3183                                // middle carriage (2)
3184                                V_writeBeamStopC2num_stop(fname,bs_num)
3185                                V_writeBeamStopC2_shape(fname,bsShapeStr)
3186                                if(cmpstr("CIRCLE",bsShapeStr)==0)
3187                                        V_writeBeamStopC2_size(fname,bs_diam)
3188                                else
3189                                        V_writeBeamStopC2_height(fname,bs_height)
3190                                        V_writeBeamStopC2_width(fname,bs_width)
3191                                endif
3192                        endif
3193               
3194                        if(cmpstr("B",carriageStr) == 0)
3195                                // back carriage (3)
3196                                V_writeBeamStopC3num_stop(fname,bs_num)
3197                                V_writeBeamStopC3_shape(fname,bsShapeStr)
3198                                if(cmpstr("CIRCLE",bsShapeStr)==0)
3199                                        V_writeBeamStopC3_size(fname,bs_diam)
3200                                else
3201                                        V_writeBeamStopC3_height(fname,bs_height)
3202                                        V_writeBeamStopC3_width(fname,bs_width)                         
3203                                endif
3204                        endif   
3205
3206                else
3207                        printf "run number %d not found\r",jj
3208                endif
3209        endfor
3210       
3211       
3212        return(0)
3213End
3214
3215
3216Proc V_Patch_SampleAperture2(lo,hi,ShapeStr,diam,width,height)
3217        Variable lo,hi
3218        String shapeStr="CIRCLE"
3219        Variable diam,width,height
3220       
3221        V_fPatch_SampleAperture2(lo,hi,ShapeStr,diam,width,height)
3222End
3223
3224//
3225// lo is the first file number
3226// hi is the last file number (inclusive)
3227//
3228// Patches sample aperture (2), the external aperture
3229//
3230// dimensions are expected to be in [cm]
3231//
3232Function V_fPatch_SampleAperture2(lo,hi,ShapeStr,diam,width,height)
3233        Variable lo,hi
3234        String ShapeStr
3235        Variable diam,width,height
3236
3237        Variable jj
3238        String fname,detStr
3239
3240               
3241        //loop over all files
3242        for(jj=lo;jj<=hi;jj+=1)
3243                fname = V_FindFileFromRunNumber(jj)
3244                if(strlen(fname) != 0)
3245               
3246                        V_writeSampleAp2_shape(fname,ShapeStr)
3247                        if(cmpstr("CIRCLE",ShapeStr)==0)
3248                                V_writeSampleAp2_size(fname,diam)
3249                        else
3250                                //RECTANGLE
3251                                V_writeSampleAp2_height(fname,height)
3252                                V_writeSampleAp2_width(fname,width)                             
3253                        endif
3254
3255                else
3256                        printf "run number %d not found\r",jj
3257                endif
3258        endfor
3259       
3260       
3261        return(0)
3262End
3263
3264
3265Proc V_Patch_MonochromatorType(lo,hi,typeStr)
3266        Variable lo,hi
3267        String typeStr="super_white_beam"
3268       
3269        V_fPatch_MonochromatorType(lo,hi,typeStr)
3270End
3271
3272//              err = V_writeMonochromatorType(fname,str)
3273Function V_fPatch_MonochromatorType(lo,hi,typeStr)
3274        Variable lo,hi
3275        String typeStr
3276
3277        Variable jj
3278        String fname
3279
3280               
3281        //loop over all files
3282        for(jj=lo;jj<=hi;jj+=1)
3283                fname = V_FindFileFromRunNumber(jj)
3284                if(strlen(fname) != 0)
3285               
3286                        V_writeMonochromatorType(fname,typeStr)
3287
3288                else
3289                        printf "run number %d not found\r",jj
3290                endif
3291        endfor
3292       
3293       
3294        return(0)
3295End
3296
3297Proc V_Patch_Wavelength(lo,hi,wavelength,delta)
3298        Variable lo,hi
3299        Variable wavelength=6.2,delta=0.8
3300       
3301        V_fPatch_Wavelength(lo,hi,wavelength,delta)
3302End
3303
3304//              err = V_writeWavelength(fname,val)
3305Function V_fPatch_Wavelength(lo,hi,lam,delta)
3306        Variable lo,hi
3307        Variable lam,delta
3308
3309        Variable jj
3310        String fname
3311
3312               
3313        //loop over all files
3314        for(jj=lo;jj<=hi;jj+=1)
3315                fname = V_FindFileFromRunNumber(jj)
3316                if(strlen(fname) != 0)
3317               
3318                        V_writeWavelength(fname,lam)
3319                        V_writeWavelength_Spread(fname,delta)
3320
3321                else
3322                        printf "run number %d not found\r",jj
3323                endif
3324        endfor
3325       
3326       
3327        return(0)
3328End
Note: See TracBrowser for help on using the repository browser.