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

Last change on this file since 1248 was 1247, checked in by srkline, 3 years ago

more changes to panel scaling so that they are viewed properly on a small-screen laptop

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