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

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

updating the IgorVersion? pragma to v7.0 for all files to be consistent.

  • 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                Variable/G gFileNum_Lo,gFileNum_Hi
2361               
2362                SetDataFolder root:
2363               
2364                Execute "V_Patch_xyCtr_Panel()"
2365        endif
2366End
2367
2368
2369// TODO:
2370// -- add method to read (import) from beam center panel
2371// x- check wave dimensions before writing (check for bad paste operation)
2372// -- load from file? different ways to import?
2373// -- add help button/file
2374// -- add done button
2375// -- adjust after user testing
2376//
2377Proc V_Patch_xyCtr_Panel() : Panel
2378        PauseUpdate; Silent 1           // building window...
2379
2380
2381        NewPanel /W=(600,400,1150,800)/N=Patch_XY_Panel /K=1
2382//      ShowTools/A
2383       
2384        ModifyPanel cbRGB=(16266,47753,2552,23355)
2385
2386        SetDrawLayer UserBack
2387        DrawText 85,99,"Current Values"
2388        DrawText 21,258,"Write to all files (inlcusive)"
2389        SetDrawEnv fsize= 14,fstyle= 1
2390        DrawText 262,30,"Beam Center [cm]"
2391        DrawText 20,133,"Run Number(s)"
2392       
2393        Button button0,pos={20,81},size={50.00,20.00},proc=V_ReadXYButtonProc,title="Read"
2394        Button button0_1,pos={20,220},size={50.00,20.00},proc=V_WriteXYButtonProc,title="Write"
2395        SetVariable setvar0,pos={20,141},size={100.00,14.00},title="first"
2396        SetVariable setvar0,value= root:Packages:NIST:VSANS:Globals:Patch:gFileNum_Lo
2397        SetVariable setvar1,pos={20.00,167},size={100.00,14.00},title="last"
2398        SetVariable setvar1,value= root:Packages:NIST:VSANS:Globals:Patch:gFileNum_Hi
2399
2400       
2401        SetDataFolder root:Packages:NIST:VSANS:Globals:Patch
2402// display the wave     
2403        Edit/W=(180,40,500,370)/HOST=#  panelW,xCtr_cm,yCtr_cm
2404        ModifyTable width(Point)=0
2405        ModifyTable width(panelW)=80
2406        ModifyTable width(xCtr_cm)=100
2407        ModifyTable width(yCtr_cm)=100
2408        RenameWindow #,T0
2409        SetActiveSubwindow ##
2410
2411        SetDataFolder root:
2412       
2413EndMacro
2414
2415
2416Function V_ReadXYButtonProc(ba) : ButtonControl
2417        STRUCT WMButtonAction &ba
2418
2419        switch( ba.eventCode )
2420                case 2: // mouse up
2421                        // click code here
2422                       
2423//                      ControlInfo popup_0
2424//                      String detStr = S_Value
2425                        ControlInfo setvar0
2426                        Variable lo=V_Value
2427                        Variable hi=lo
2428                       
2429                        V_fReadDet_xyCenters(lo,hi)
2430                       
2431                        break
2432                case -1: // control being killed
2433                        break
2434        endswitch
2435
2436        return 0
2437End
2438
2439Function V_WriteXYButtonProc(ba) : ButtonControl
2440        STRUCT WMButtonAction &ba
2441
2442        switch( ba.eventCode )
2443                case 2: // mouse up
2444                        // click code here
2445                       
2446//                      ControlInfo popup_0
2447//                      String detStr = S_Value
2448                        ControlInfo setvar0
2449                        Variable lo=V_Value
2450                        ControlInfo setvar1
2451                        Variable hi=V_Value
2452//                      Wave deadTimeW = root:Packages:NIST:VSANS:Globals:Patch:deadTimeWave
2453
2454// this function will write the new centers to the file and then delete the file from
2455// RawVSANS to force a re-read of the data                     
2456                        V_fPatchDet_xyCenters(lo,hi)
2457
2458                        break
2459                case -1: // control being killed
2460                        break
2461        endswitch
2462
2463        return 0
2464End
2465
2466//////////////////////////////////////////////////////////////////////////////////////////////////
2467//////////////////////////////////////////////////////////////////////////////////////////////////
2468
2469
2470Proc V_PatchDet_Offset(lo,hi)
2471        Variable lo,hi
2472       
2473        V_fPatchDet_Offset(lo,hi)
2474End
2475
2476Proc V_MarkLeftRightFlip_Done(lo,hi)
2477        Variable lo,hi
2478       
2479        V_fWriteFlipState(lo,hi,1)      // value == 1 means flip done
2480End
2481
2482Proc V_MarkLeftRightFlip_Not_Done(lo,hi)
2483        Variable lo,hi
2484       
2485        V_fWriteFlipState(lo,hi,-999999)        // value == -999999 means flip not done
2486End
2487
2488
2489Proc V_Patch_GroupID_catTable()
2490        V_fPatch_GroupID_catTable()
2491end
2492
2493Proc V_Patch_Purpose_catTable()
2494        V_fPatch_Purpose_catTable()
2495end
2496
2497Proc V_Patch_Intent_catTable()
2498        V_fPatch_Intent_catTable()
2499end
2500
2501Proc V_PatchDet_Gap(lo,hi)
2502        Variable lo,hi
2503       
2504        V_fPatchDet_Gap(lo,hi)
2505End
2506
2507Proc V_ReadDet_Gap(lo,hi)
2508        Variable lo,hi
2509       
2510        V_fReadDet_Gap(lo,hi)
2511End
2512
2513Proc V_PatchDet_Distance(lo,hi,dist_f,dist_m,dist_b)
2514        Variable lo,hi,dist_f=400,dist_m=1900,dist_b=2200
2515       
2516        V_fPatchDet_distance(lo,hi,dist_f,dist_m,dist_b)
2517End
2518
2519Proc V_Patch_Back_Detector(lo,hi)
2520        Variable lo,hi
2521       
2522        V_fPatch_BackDetector(lo,hi)
2523End
2524
2525Proc V_Patch_Back_XYPixelSize(lo,hi)
2526        Variable lo,hi
2527       
2528        V_fPatch_BackDetectorPixel(lo,hi)
2529end
2530
2531Proc V_Patch_XYPixelSize(lo,hi)
2532        Variable lo,hi
2533       
2534        V_fPatch_XYPixelSize(lo,hi)
2535End
2536
2537// simple utility to patch the offset values in the file headers
2538//
2539// Swaps only the L/R detector values
2540// lo is the first file number
2541// hi is the last file number (inclusive)
2542//
2543//              V_getLeftRightFlipDone(fname)
2544//
2545//
2546// updated the function to check for the "already done" flag
2547// - if already done, report this and do nothing.
2548// - if not done, do the flip and set the flag
2549//
2550Function V_fPatchDet_Offset(lo,hi)
2551        Variable lo,hi
2552
2553       
2554        Variable ii,jj,flipDone=0
2555        String fname,detStr
2556       
2557        Variable offset_ML,offset_MR,offset_FL,offset_FR
2558
2559       
2560        //loop over all files
2561        for(jj=lo;jj<=hi;jj+=1)
2562                fname = V_FindFileFromRunNumber(jj)
2563                if(strlen(fname) != 0)
2564               
2565                        flipDone = V_getLeftRightFlipDone(fname)
2566                        if(flipDone == 1)
2567                                printf "run number %d already flipped - nothing done\r",jj
2568                        else
2569                                offset_FL = V_getDet_LateralOffset(fname,"FL")
2570                                offset_FR = V_getDet_LateralOffset(fname,"FR")
2571       
2572                                offset_ML = V_getDet_LateralOffset(fname,"ML")
2573                                offset_MR = V_getDet_LateralOffset(fname,"MR")
2574                       
2575                        // swap L/R offset values
2576                                V_WriteDet_LateralOffset(fname,"FL",-offset_FR)
2577                                V_WriteDet_LateralOffset(fname,"FR",-offset_FL)
2578                               
2579                                V_WriteDet_LateralOffset(fname,"ML",-offset_MR)
2580                                V_WriteDet_LateralOffset(fname,"MR",-offset_ML)
2581                       
2582                        // set the flag
2583                                V_writeLeftRightFlipDone(fname,1)               // value == 1 means the flip was done
2584                                Print fname
2585                                Print "swapped FL, FR = ",-offset_FR,-offset_FL
2586                                Print "swapped ML, MR = ",-offset_MR,-offset_ML
2587                       
2588                        endif
2589               
2590                else
2591                        printf "run number %d not found\r",jj
2592                endif
2593               
2594        endfor
2595       
2596        return(0)
2597End
2598
2599//  utility to reset the flip state in the file headers
2600//
2601// lo is the first file number
2602// hi is the last file number (inclusive)
2603//
2604// setting value == 1 means done
2605// setting value == -999999 means not done (mimics a missing /entry)
2606//
2607Function V_fWriteFlipState(lo,hi,val)
2608        Variable lo,hi,val
2609
2610       
2611        Variable ii,jj,flipDone=0
2612        String fname,detStr
2613       
2614        Variable offset_ML,offset_MR,offset_FL,offset_FR
2615
2616        //loop over all files
2617        for(jj=lo;jj<=hi;jj+=1)
2618                fname = V_FindFileFromRunNumber(jj)
2619                if(strlen(fname) != 0)
2620       
2621                // set the flag
2622                        V_writeLeftRightFlipDone(fname,val)             //
2623                        Print fname
2624                        printf "run number %d flag reset to %d\r",jj,val
2625                       
2626                else
2627                        printf "run number %d not found\r",jj
2628                endif
2629               
2630        endfor
2631       
2632        return(0)
2633End
2634
2635
2636
2637// simple utility to read the detector offset stored in the file header
2638Function V_fReadDet_Offset(lo,hi)
2639        Variable lo,hi
2640
2641        String fname,detStr
2642        Variable jj
2643        Variable offset_ML,offset_MR,offset_FL,offset_FR
2644       
2645        for(jj=lo;jj<=hi;jj+=1)
2646                fname = V_FindFileFromRunNumber(jj)
2647                if(strlen(fname) != 0)
2648               
2649                        offset_FL = V_getDet_LateralOffset(fname,"FL")
2650                        offset_FR = V_getDet_LateralOffset(fname,"FR")
2651
2652                        offset_ML = V_getDet_LateralOffset(fname,"ML")
2653                        offset_MR = V_getDet_LateralOffset(fname,"MR")
2654               
2655                        Print fname
2656                        Print "FL, FR = ",offset_FL,offset_FR
2657                        Print "ML, MR = ",offset_ML,offset_MR
2658               
2659               
2660                else
2661                        printf "run number %d not found\r",jj
2662                endif
2663               
2664        endfor
2665
2666       
2667        return(0)
2668End
2669
2670
2671// patches the group_ID, based on whatever is in the catTable
2672//
2673Function V_fPatch_GroupID_catTable()
2674        Variable lo,hi
2675
2676       
2677        Variable ii,jj,num
2678       
2679        Wave id = root:Packages:NIST:VSANS:CatVSHeaderInfo:Group_ID
2680        Wave/T fileNameW = root:Packages:NIST:VSANS:CatVSHeaderInfo:Filenames
2681
2682        num = numpnts(id)       
2683        //loop over all files
2684        for(jj=0;jj<num;jj+=1)
2685                Print "update file ",jj,fileNameW[jj]
2686                V_writeSample_GroupID(fileNameW[jj],id[jj])     
2687        endfor
2688       
2689        return(0)
2690End
2691
2692
2693// patches the Purpose, based on whatever is in the catTable
2694//
2695Function V_fPatch_Purpose_catTable()
2696        Variable lo,hi
2697
2698       
2699        Variable ii,jj,num
2700       
2701        Wave/T purpose = root:Packages:NIST:VSANS:CatVSHeaderInfo:Purpose
2702        Wave/T fileNameW = root:Packages:NIST:VSANS:CatVSHeaderInfo:Filenames
2703
2704        num = numpnts(purpose) 
2705        //loop over all files
2706        for(jj=0;jj<num;jj+=1)
2707                Print "update file ",jj,fileNameW[jj]
2708                V_writeReduction_Purpose(fileNameW[jj],purpose[jj])     
2709        endfor
2710       
2711        return(0)
2712End
2713
2714// patches the Intent, based on whatever is in the catTable
2715//
2716Function V_fPatch_Intent_catTable()
2717        Variable lo,hi
2718
2719       
2720        Variable ii,jj,num
2721       
2722        Wave/T intent = root:Packages:NIST:VSANS:CatVSHeaderInfo:Intent
2723        Wave/T fileNameW = root:Packages:NIST:VSANS:CatVSHeaderInfo:Filenames
2724
2725        num = numpnts(intent)   
2726        //loop over all files
2727        for(jj=0;jj<num;jj+=1)
2728                Print "update file ",jj,fileNameW[jj]
2729                V_writeReductionIntent(fileNameW[jj],intent[jj])       
2730        endfor
2731       
2732        return(0)
2733End
2734
2735
2736
2737// simple utility to patch the detector gap values in the file headers
2738//
2739// values are measured values in [mm], not estimated
2740//
2741// lo is the first file number
2742// hi is the last file number (inclusive)
2743//
2744Function V_fPatchDet_Gap(lo,hi)
2745        Variable lo,hi
2746
2747       
2748        Variable ii,jj
2749        String fname,detStr
2750               
2751        //loop over all files
2752        for(jj=lo;jj<=hi;jj+=1)
2753                fname = V_FindFileFromRunNumber(jj)
2754                if(strlen(fname) != 0)
2755               
2756                // write gap values
2757                        V_writeDet_panel_gap(fname,"FL",3.5)
2758                        V_writeDet_panel_gap(fname,"FR",3.5)
2759
2760                        V_writeDet_panel_gap(fname,"FT",3.3)
2761                        V_writeDet_panel_gap(fname,"FB",3.3)
2762
2763                        V_writeDet_panel_gap(fname,"ML",5.9)
2764                        V_writeDet_panel_gap(fname,"MR",5.9)
2765
2766                        V_writeDet_panel_gap(fname,"MT",18.3)
2767                        V_writeDet_panel_gap(fname,"MB",18.3)           
2768               
2769                else
2770                        printf "run number %d not found\r",jj
2771                endif
2772        endfor
2773       
2774        return(0)
2775End
2776
2777// simple utility to read the detector gap values stored in the file header
2778Function V_fReadDet_Gap(lo,hi)
2779        Variable lo,hi
2780
2781        String fname,detStr
2782        Variable jj
2783        Variable gap_FL,gap_FR,gap_FT,gap_FB,gap_ML,gap_MR,gap_MT,gap_MB
2784       
2785        for(jj=lo;jj<=hi;jj+=1)
2786                fname = V_FindFileFromRunNumber(jj)
2787                if(strlen(fname) != 0)
2788               
2789                        gap_FL = V_getDet_panel_gap(fname,"FL")
2790                        gap_FR = V_getDet_panel_gap(fname,"FR")
2791                        gap_FT = V_getDet_panel_gap(fname,"FT")
2792                        gap_FB = V_getDet_panel_gap(fname,"FB")
2793
2794                        gap_ML = V_getDet_panel_gap(fname,"ML")
2795                        gap_MR = V_getDet_panel_gap(fname,"MR")
2796                        gap_MT = V_getDet_panel_gap(fname,"MT")
2797                        gap_MB = V_getDet_panel_gap(fname,"MB")
2798                       
2799                        print fname     
2800                        Print "FL, FR, FT, FB = ",gap_FL,gap_FR,gap_FT,gap_FB
2801                        Print "ML, MR, MT, MB = ",gap_ML,gap_MR,gap_MT,gap_MB
2802               
2803               
2804                else
2805                        printf "run number %d not found\r",jj
2806                endif
2807               
2808        endfor
2809
2810       
2811        return(0)
2812End
2813
2814
2815// simple utility to patch the detector distance values in the file headers
2816//
2817// values are in [cm]
2818//
2819// lo is the first file number
2820// hi is the last file number (inclusive)
2821//
2822Function V_fPatchDet_distance(lo,hi,d_f,d_m,d_b)
2823        Variable lo,hi,d_f,d_m,d_b
2824
2825       
2826        Variable ii,jj
2827        String fname,detStr
2828               
2829        //loop over all files
2830        for(jj=lo;jj<=hi;jj+=1)
2831                fname = V_FindFileFromRunNumber(jj)
2832                if(strlen(fname) != 0)
2833               
2834                // write gap values
2835                        V_writeDet_distance(fname,"FL",d_f)
2836                        V_writeDet_distance(fname,"FR",d_f)
2837                        V_writeDet_distance(fname,"FT",d_f)
2838                        V_writeDet_distance(fname,"FB",d_f)
2839
2840                        V_writeDet_distance(fname,"ML",d_m)
2841                        V_writeDet_distance(fname,"MR",d_m)
2842                        V_writeDet_distance(fname,"MT",d_m)
2843                        V_writeDet_distance(fname,"MB",d_m)             
2844
2845                        V_writeDet_distance(fname,"B",d_b)             
2846               
2847                else
2848                        printf "run number %d not found\r",jj
2849                endif
2850        endfor
2851       
2852        return(0)
2853End
2854
2855
2856//
2857// simple utility to patch all of the values associated with the back detector
2858//
2859// as of Dec 2019, this is not used any longer as these values are all written correctly,
2860// except for patching old data with the XY pixel dimensions (separate macro)
2861//
2862//
2863// lo is the first file number
2864// hi is the last file number (inclusive)
2865//
2866Function V_fPatch_BackDetector(lo,hi)
2867        Variable lo,hi
2868
2869       
2870        Variable ii,jj
2871        String fname,detStr
2872       
2873        detStr = "B"
2874       
2875        Make/O/D/N=3 cal_x,cal_y
2876        cal_x[0] = VCALC_getPixSizeX(detStr)                    // pixel size in VCALC_getPixSizeX(detStr) is [cm]
2877        cal_x[1] = 1
2878        cal_x[2] = 10000
2879        cal_y[0] = VCALC_getPixSizeY(detStr)                    // pixel size in VCALC_getPixSizeX(detStr) is [cm]
2880        cal_y[1] = 1
2881        cal_y[2] = 10000
2882       
2883        Make/O/I/N=(680,1656) tmpData=1
2884       
2885        //loop over all files
2886        for(jj=lo;jj<=hi;jj+=1)
2887                fname = V_FindFileFromRunNumber(jj)
2888                if(strlen(fname) != 0)
2889               
2890                // patch cal_x and cal_y
2891                        V_writeDet_cal_x(fname,detStr,cal_x)
2892                        V_writeDet_cal_y(fname,detStr,cal_y)
2893               
2894                // patch n_pix_x and y
2895                        V_writeDet_pixel_num_x(fname,detStr,680)
2896                        V_writeDet_pixel_num_y(fname,detStr,1656)
2897                       
2898                // patch pixel size x and y [cm]
2899                        V_writeDet_x_pixel_size(fname,detStr,0.034)
2900                        V_writeDet_y_pixel_size(fname,detStr,0.034)
2901                       
2902                // patch dead time
2903                // TODO: enter a proper value here once it's actually measured
2904                        V_writeDetector_deadtime_B(fname,detStr,1e-20)
2905               
2906                // patch fwhm_x and y
2907                // TODO: verify the values once they are measured, and also the UNITS!!! [cm]???
2908                        V_writeDet_pixel_fwhm_x(fname,detStr,0.034)
2909                        V_writeDet_pixel_fwhm_y(fname,detStr,0.034)
2910               
2911                // patch beam center (nominal x,y) [cm] values
2912                        V_writeDet_beam_center_x(fname,detStr,11)
2913                        V_writeDet_beam_center_y(fname,detStr,25)
2914               
2915                // fake data
2916//                      V_writeDetectorData(fname,detStr,tmpData)
2917                       
2918                       
2919                else
2920                        printf "run number %d not found\r",jj
2921                endif
2922        endfor
2923       
2924        KillWaves/Z cal_x,cal_y,tmpData
2925        return(0)
2926End
2927
2928
2929//
2930// simple utility to patch the X and Y Pixel dimensions for the back detector
2931// the cal_x(y) values are what is actually used to calculate the real space distance
2932// and then ultimately the q-values.
2933//
2934// **this updated value for the pixel size is from a measurement of a grid of pinholes
2935// as a mask in front of the detector (done in Sept 2019,  run 43550 - calculations
2936// done in Dec 2019)
2937//
2938//
2939// lo is the first file number
2940// hi is the last file number (inclusive)
2941//
2942Function V_fPatch_BackDetectorPixel(lo,hi)
2943        Variable lo,hi
2944
2945       
2946        Variable ii,jj
2947        String fname,detStr
2948       
2949        detStr = "B"
2950       
2951        Make/O/D/N=3 cal_x,cal_y
2952        cal_x[0] = 0.03175                      // pixel size in VCALC_getPixSizeX(detStr) is [cm]
2953        cal_x[1] = 1
2954        cal_x[2] = 10000
2955        cal_y[0] = 0.03175              // pixel size in VCALC_getPixSizeX(detStr) is [cm]
2956        cal_y[1] = 1
2957        cal_y[2] = 10000
2958       
2959       
2960        //loop over all files
2961        for(jj=lo;jj<=hi;jj+=1)
2962                fname = V_FindFileFromRunNumber(jj)
2963                if(strlen(fname) != 0)
2964               
2965                // patch cal_x and cal_y
2966                        V_writeDet_cal_x(fname,detStr,cal_x)
2967                        V_writeDet_cal_y(fname,detStr,cal_y)
2968                               
2969                // patch pixel size x and y [cm]
2970                        V_writeDet_x_pixel_size(fname,detStr,0.03175)
2971                        V_writeDet_y_pixel_size(fname,detStr,0.03175)
2972                                       
2973                else
2974                        printf "run number %d not found\r",jj
2975                endif
2976        endfor
2977       
2978        KillWaves/Z cal_x,cal_y
2979        return(0)
2980End
2981
2982
2983
2984//
2985// simple utility to patch all of the pixel sizes
2986// - in the header, the Y size for LR panels was grossly wrong (4 mm)
2987// and all of the values are slightly off from the true values
2988//
2989// data collected after 10/3/18 should not need this patch since the
2990// config.js file was updated
2991//
2992//
2993//
2994// lo is the first file number
2995// hi is the last file number (inclusive)
2996//
2997Function V_fPatch_XYPixelSize(lo,hi)
2998        Variable lo,hi
2999
3000       
3001        Variable ii,jj
3002        String fname,detStr
3003       
3004       
3005        //loop over all files
3006        for(jj=lo;jj<=hi;jj+=1)
3007                fname = V_FindFileFromRunNumber(jj)
3008                if(strlen(fname) != 0)
3009                       
3010                // patch pixel size x and y [cm] L/R panels
3011                        V_writeDet_x_pixel_size(fname,"FL",8.4)
3012                        V_writeDet_y_pixel_size(fname,"FL",8.14)
3013
3014                        V_writeDet_x_pixel_size(fname,"FR",8.4)
3015                        V_writeDet_y_pixel_size(fname,"FR",8.14)                       
3016
3017                        V_writeDet_x_pixel_size(fname,"ML",8.4)
3018                        V_writeDet_y_pixel_size(fname,"ML",8.14)
3019
3020                        V_writeDet_x_pixel_size(fname,"MR",8.4)
3021                        V_writeDet_y_pixel_size(fname,"MR",8.14)
3022                       
3023                // patch pixel size x and y [cm] T/B panels
3024                        V_writeDet_x_pixel_size(fname,"FT",4.16)
3025                        V_writeDet_y_pixel_size(fname,"FT",8.4)
3026
3027                        V_writeDet_x_pixel_size(fname,"FB",4.16)
3028                        V_writeDet_y_pixel_size(fname,"FB",8.4)                 
3029
3030                        V_writeDet_x_pixel_size(fname,"MT",4.16)
3031                        V_writeDet_y_pixel_size(fname,"MT",8.4)
3032
3033                        V_writeDet_x_pixel_size(fname,"MB",4.16)
3034                        V_writeDet_y_pixel_size(fname,"MB",8.4)                 
3035                       
3036                else
3037                        printf "run number %d not found\r",jj
3038                endif
3039        endfor
3040       
3041        return(0)
3042End
3043
3044
3045Proc V_Patch_Guide_SSD_Aperture(lo,hi,numGuideStr,sourceDiam_mm)
3046        Variable lo,hi
3047        String numGuideStr="CONV_BEAMS"
3048        Variable sourceDiam_mm=30
3049       
3050        V_fPatch_Guide_SSD_Aperture(lo,hi,numGuideStr,sourceDiam_mm)
3051End
3052
3053
3054
3055// simple utility to patch all three at once, since they are all linked and typically
3056/// are all incorrectly entered by NICE if the number of guides can't be determined
3057//
3058// Number of guides
3059// source aperture to gate valve distance [cm]
3060// source aperture diameter [mm]
3061//
3062// the source aperture is assumed to be circular and the diameter in mm
3063//
3064// the value for the A1_to_GV is from tabulated values.  (see VC_calcSSD)
3065// This is the Source aperture to Gate Valve distance
3066//
3067//
3068// lo is the first file number
3069// hi is the last file number (inclusive)
3070//
3071Function V_fPatch_Guide_SSD_Aperture(lo,hi,numGuideStr,sourceDiam_mm)
3072        Variable lo,hi
3073        String numGuideStr
3074        Variable sourceDiam_mm
3075
3076       
3077        Variable ii,jj,A1_to_GV
3078        String fname,detStr
3079
3080        strswitch(numGuideStr)
3081                case "CONV_BEAMS":
3082                case "NARROW_SLITS":
3083                case "0":
3084                                A1_to_GV = 2441
3085                        break
3086                case "1":
3087                                A1_to_GV = 2157
3088                        break
3089                case "2":
3090                                A1_to_GV = 1976
3091                        break
3092                case "3":
3093                                A1_to_GV = 1782
3094                        break                   
3095                case "4":
3096                                A1_to_GV = 1582
3097                        break                   
3098                case "5":
3099                                A1_to_GV = 1381
3100                        break                   
3101                case "6":
3102                                A1_to_GV = 1181
3103                        break                   
3104                case "7":
3105                                A1_to_GV = 980
3106                        break                   
3107                case "8":
3108                                A1_to_GV = 780
3109                        break                   
3110                case "9":
3111                                A1_to_GV = 579
3112                        break                   
3113                default:
3114                        Print "Error - using default A1_to_GV value"
3115                        A1_to_GV = 2441
3116        endswitch
3117
3118               
3119        //loop over all files
3120        for(jj=lo;jj<=hi;jj+=1)
3121                fname = V_FindFileFromRunNumber(jj)
3122                if(strlen(fname) != 0)
3123               
3124                // write values
3125                V_writeNumberOfGuides(fname,numGuideStr)
3126
3127                V_writeSourceAp_distance(fname,A1_to_GV)
3128
3129                V_writeSourceAp_shape(fname,"CIRCLE")
3130                V_writeSourceAp_size(fname,num2str(sourceDiam_mm))
3131
3132                else
3133                        printf "run number %d not found\r",jj
3134                endif
3135        endfor
3136       
3137        return(0)
3138End
3139
3140
3141//
3142// pick the carriage, beamstop number, beamstop shape, and beamstop diameter
3143// or height and width
3144Proc V_Patch_BeamStop(lo,hi,carriageStr,bs_num,bsShapeStr,bs_diam,bs_width,bs_height)
3145        Variable lo,hi
3146        String carriageStr="B"
3147        Variable bs_num=2
3148        String bsShapeStr="CIRCLE"
3149        Variable bs_diam=12,bs_width=12,bs_height=300
3150       
3151        V_fPatch_BeamStop(lo,hi,carriageStr,bs_num,bsShapeStr,bs_diam,bs_width,bs_height)
3152End
3153
3154
3155//
3156// lo is the first file number
3157// hi is the last file number (inclusive)
3158//
3159Function V_fPatch_BeamStop(lo,hi,carriageStr,bs_num,bsShapeStr,bs_diam,bs_width,bs_height)
3160        Variable lo,hi
3161        String carriageStr
3162        Variable bs_num
3163        String bsShapeStr
3164        Variable bs_diam,bs_width,bs_height
3165
3166       
3167        Variable ii,jj,A1_to_GV
3168        String fname,detStr
3169
3170               
3171        //loop over all files
3172        for(jj=lo;jj<=hi;jj+=1)
3173                fname = V_FindFileFromRunNumber(jj)
3174                if(strlen(fname) != 0)
3175
3176                        if(cmpstr("F",carriageStr) == 0)
3177                                Print "front carriage has no beamstops"
3178                        endif
3179                       
3180                        if(cmpstr("M",carriageStr) == 0)
3181                                // middle carriage (2)
3182                                V_writeBeamStopC2num_stop(fname,bs_num)
3183                                V_writeBeamStopC2_shape(fname,bsShapeStr)
3184                                if(cmpstr("CIRCLE",bsShapeStr)==0)
3185                                        V_writeBeamStopC2_size(fname,bs_diam)
3186                                else
3187                                        V_writeBeamStopC2_height(fname,bs_height)
3188                                        V_writeBeamStopC2_width(fname,bs_width)
3189                                endif
3190                        endif
3191               
3192                        if(cmpstr("B",carriageStr) == 0)
3193                                // back carriage (3)
3194                                V_writeBeamStopC3num_stop(fname,bs_num)
3195                                V_writeBeamStopC3_shape(fname,bsShapeStr)
3196                                if(cmpstr("CIRCLE",bsShapeStr)==0)
3197                                        V_writeBeamStopC3_size(fname,bs_diam)
3198                                else
3199                                        V_writeBeamStopC3_height(fname,bs_height)
3200                                        V_writeBeamStopC3_width(fname,bs_width)                         
3201                                endif
3202                        endif   
3203
3204                else
3205                        printf "run number %d not found\r",jj
3206                endif
3207        endfor
3208       
3209       
3210        return(0)
3211End
3212
3213
3214Proc V_Patch_SampleAperture2(lo,hi,ShapeStr,diam,width,height)
3215        Variable lo,hi
3216        String shapeStr="CIRCLE"
3217        Variable diam,width,height
3218       
3219        V_fPatch_SampleAperture2(lo,hi,ShapeStr,diam,width,height)
3220End
3221
3222//
3223// lo is the first file number
3224// hi is the last file number (inclusive)
3225//
3226// Patches sample aperture (2), the external aperture
3227//
3228// dimensions are expected to be in [cm]
3229//
3230Function V_fPatch_SampleAperture2(lo,hi,ShapeStr,diam,width,height)
3231        Variable lo,hi
3232        String ShapeStr
3233        Variable diam,width,height
3234
3235        Variable jj
3236        String fname,detStr
3237
3238               
3239        //loop over all files
3240        for(jj=lo;jj<=hi;jj+=1)
3241                fname = V_FindFileFromRunNumber(jj)
3242                if(strlen(fname) != 0)
3243               
3244                        V_writeSampleAp2_shape(fname,ShapeStr)
3245                        if(cmpstr("CIRCLE",ShapeStr)==0)
3246                                V_writeSampleAp2_size(fname,diam)
3247                        else
3248                                //RECTANGLE
3249                                V_writeSampleAp2_height(fname,height)
3250                                V_writeSampleAp2_width(fname,width)                             
3251                        endif
3252
3253                else
3254                        printf "run number %d not found\r",jj
3255                endif
3256        endfor
3257       
3258       
3259        return(0)
3260End
3261
3262
3263Proc V_Patch_MonochromatorType(lo,hi,typeStr)
3264        Variable lo,hi
3265        String typeStr="super_white_beam"
3266       
3267        V_fPatch_MonochromatorType(lo,hi,typeStr)
3268End
3269
3270//              err = V_writeMonochromatorType(fname,str)
3271Function V_fPatch_MonochromatorType(lo,hi,typeStr)
3272        Variable lo,hi
3273        String typeStr
3274
3275        Variable jj
3276        String fname
3277
3278               
3279        //loop over all files
3280        for(jj=lo;jj<=hi;jj+=1)
3281                fname = V_FindFileFromRunNumber(jj)
3282                if(strlen(fname) != 0)
3283               
3284                        V_writeMonochromatorType(fname,typeStr)
3285
3286                else
3287                        printf "run number %d not found\r",jj
3288                endif
3289        endfor
3290       
3291       
3292        return(0)
3293End
3294
3295Proc V_Patch_Wavelength(lo,hi,wavelength,delta)
3296        Variable lo,hi
3297        Variable wavelength=6.2,delta=0.8
3298       
3299        V_fPatch_Wavelength(lo,hi,wavelength,delta)
3300End
3301
3302//              err = V_writeWavelength(fname,val)
3303Function V_fPatch_Wavelength(lo,hi,lam,delta)
3304        Variable lo,hi
3305        Variable lam,delta
3306
3307        Variable jj
3308        String fname
3309
3310               
3311        //loop over all files
3312        for(jj=lo;jj<=hi;jj+=1)
3313                fname = V_FindFileFromRunNumber(jj)
3314                if(strlen(fname) != 0)
3315               
3316                        V_writeWavelength(fname,lam)
3317                        V_writeWavelength_Spread(fname,delta)
3318
3319                else
3320                        printf "run number %d not found\r",jj
3321                endif
3322        endfor
3323       
3324       
3325        return(0)
3326End
Note: See TracBrowser for help on using the repository browser.