source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/VSANS/V_EventModeProcessing.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

File size: 93.6 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma IgorVersion=6.22
3#pragma IgorVersion = 7.00
4
5
6/////////////
7//VSANS Event File Format
8// (Phil Chabot)
9//////////////
10//
11// The event file shall be of binary format, with data encoded in little endian format.
12// The file shall have a header section and a data section
13//
14//Header -- The header will contain the following:
15//File byte offset              Size (bytes)            Value                           Description
16//              0                                                       5                               'VSANS'                         magic number
17//              5                                                       2                               0xMajorMinor            Revision number = 0x00
18//              7                                                       2                               n bytes                         Offset to data in bytes
19//              9                                                       10                              IEEE1588 - UTC  time origin for timestamp, IEEE1588 UTC
20//              19                                                      1                               'F'/'M'/'R'                     detector carriage group
21//              20                                                      2                               HV (V)                          HV Reading in Volt
22//              22                                                      4                               clk (Hz)                                timestamp clock frequency in Hz
23//              26                                                      N                               tubeID                          disabled tubes # ; 1 byte/tube if any
24
25//Data
26//
27//File byte offset              Size (bytes)            Value                           Description
28//              0                                                       1                               tubeID                          tube index - 0-191
29//              1                                                       1                               pixel                                   pixel value [0:127]
30//              2                                                       6                               timestamp                       timestamp in resolution unit
31//              8                                                       1                               tubeID                          

32//              
                                                     â€Š                             â€Š                                             â€Š
33
34//
35// Time of origin for timestamp should be in UTC. Any disabled detector tubes can be reported in the header section.
36// If timestamp n is superior to timestamp n+1, then timestamp n is corrupted. To be discussed. 
37//
38// There is no event mode data for the High Resolution (back) detector
39//
40// each carriage (M, F) is in a single event file. Tubes are numbered 0->(4*48)-1 == 0->191 and once
41// the event data is decoded, the histogram can be split into the 4 panels.
42//
43// Based on the numbering 0-191:
44// group 1 = R (0,47)                   MatrixOp out = ReverseRows(in)
45// group 2 = T (48,95)          output = slices_T[q][p][r]
46// group 3 = B (96,143)                 output = slices_B[XBINS-q-1][YBINS-p-1][r]              (reverses rows and columns)
47// group 4 = L (144,191)        MatrixOp out = ReverseCols(in)
48//
49// the transformation flips the panel to the view as if the detector was viewed from the sample position
50// (this is the standard view for SANS and VSANS)
51//
52////////////////////
53
54
55//
56// Event mode prcessing for VSANS
57//
58// First pass, getting the basics to work
59//
60// x- need TOF processing for wavelength calibration
61//  x- document this so it can be done quickly and easily.
62//
63
64
65
66
67// TODO:
68//
69// -- Can any of this be multithreaded?
70//  -- the histogram operation, the Indexing for the histogram, all are candidates
71//  -- can the decoding be multithreaded as a wave assignment speedup?
72//
73//
74// -- search for TODO for unresolved issues not on this list
75//
76// -- add comments to the code as needed
77//
78// -- write the help file, and link the help buttons to the help docs
79//
80// -- examples?
81//
82//
83// X- the slice display "fails" for data sets that have 3 or 4 slices, as the ModifyImage command
84//     interprets the data as being RGB - and so does nothing.
85//     need to find a way around this. This was fixed by displaying the data using the G=1 flag on AppendImage
86//     to prevent the "atuo-detection" of data as RGB
87//
88//
89///////////////   SWITCHES     /////////////////
90//
91// for the "File Too Big" limit:
92//      Variable/G root:Packages:NIST:VSANS:Event:gEventFileTooLarge = 150              // 150 MB considered too large
93//
94// for the tolerance of "step" detection
95//      Variable/G root:Packages:NIST:VSANS:Event:gStepTolerance = 5            // 5 = # of standard deviations from mean. See PutCursorsAtStep()
96//
97//
98//
99//
100
101
102// 
103// x- these dimensions are hard-wired
104//
105// XBINS is for an individual panel
106// NTUBES is the total number of tubes = (4)(48)=192
107//
108Constant XBINS=48
109Constant NTUBES=192
110Constant YBINS=128
111
112Static Constant MODE_STREAM = 0
113Static Constant MODE_OSCILL = 1
114Static Constant MODE_TISANE = 2
115Static Constant MODE_TOF = 3
116
117
118
119// Initialization of the VSANS event mode panel
120Proc V_Show_Event_Panel()
121        DoWindow/F VSANS_EventModePanel
122        if(V_flag ==0)
123                V_Init_Event()
124                VSANS_EventModePanel()
125        EndIf
126End
127
128//
129//  x- need an index table with the tube <-> panel correspondence
130//    NO, per Phil, the tube numbering is sequential:
131//
132// Based on the numbering 0-191:
133// group 1 = R (0,47)                   MatrixOp out = ReverseRows(in)
134// group 2 = T (48,95)          output = slices_T[q][p][r]
135// group 3 = B (96,143)                 output = slices_B[XBINS-q-1][YBINS-p-1][r]              (reverses rows and columns)
136// group 4 = L (144,191)        MatrixOp out = ReverseCols(in)
137//
138// There is a separate function that does the proper flipping to get the panels into the correct orientation
139//
140Function V_Init_Event()
141
142        NewDataFolder/O/S root:Packages:NIST:VSANS:Event
143
144        String/G        root:Packages:NIST:VSANS:Event:gEvent_logfile
145        String/G        root:Packages:NIST:VSANS:Event:gEventDisplayString="Details of the file load"
146
147
148// globals that are the header of the VSANS event file
149        String/G root:Packages:NIST:VSANS:Event:gVsansStr=""
150        Variable/G root:Packages:NIST:VSANS:Event:gRevision = 0
151        Variable/G root:Packages:NIST:VSANS:Event:gOffset=0             // = 25 bytes if no disabled tubes
152        Variable/G root:Packages:NIST:VSANS:Event:gTime1=0
153        Variable/G root:Packages:NIST:VSANS:Event:gTime2=0
154        Variable/G root:Packages:NIST:VSANS:Event:gTime3=0
155        Variable/G root:Packages:NIST:VSANS:Event:gTime4=0      // these 4 time pieces are supposed to be 8 bytes total
156        Variable/G root:Packages:NIST:VSANS:Event:gTime5=0      // these 5 time pieces are supposed to be 10 bytes total
157        String/G root:Packages:NIST:VSANS:Event:gDetStr=""
158        Variable/G root:Packages:NIST:VSANS:Event:gVolt=0
159        Variable/G root:Packages:NIST:VSANS:Event:gResol=0              //time resolution in nanoseconds
160// TODO -- need a wave? for the list of disabled tubes
161// don't know how many there might be, or why I would need to know
162
163        Variable/G root:Packages:NIST:VSANS:Event:gEvent_t_longest = 0
164
165        Variable/G root:Packages:NIST:VSANS:Event:gEvent_tsdisp //Displayed slice
166        Variable/G root:Packages:NIST:VSANS:Event:gEvent_nslices = 10  //Number of time slices
167       
168        Variable/G root:Packages:NIST:VSANS:Event:gEvent_logint = 1
169
170        Variable/G root:Packages:NIST:VSANS:Event:gEvent_Mode = 0                               // ==0 for "stream", ==1 for Oscillatory
171        Variable/G root:Packages:NIST:VSANS:Event:gRemoveBadEvents = 1          // ==1 to remove "bad" events, ==0 to read "as-is"
172        Variable/G root:Packages:NIST:VSANS:Event:gSortStreamEvents = 0         // ==1 to sort the event stream, a last resort for a stream of data
173       
174        Variable/G root:Packages:NIST:VSANS:Event:gEvent_ForceTmaxBin=1         //==1 to enforce t_longest in user-defined custom bins
175
176        NVAR nslices = root:Packages:NIST:VSANS:Event:gEvent_nslices
177       
178               
179        Make/D/O/N=(XBINS,YBINS,nslices) slicedData
180        Duplicate/O slicedData logslicedData
181        Duplicate/O slicedData dispsliceData
182
183
184// for decimation (not used for VSANS - may be added back in the future)
185        Variable/G root:Packages:NIST:VSANS:Event:gEventFileTooLarge = 1501             // 1500 MB considered too large
186        Variable/G root:Packages:NIST:VSANS:Event:gDecimation = 100
187        Variable/G root:Packages:NIST:VSANS:Event:gEvent_t_longest_decimated = 0
188
189// for large file splitting (unused)
190        String/G root:Packages:NIST:VSANS:Event:gSplitFileList = ""             // a list of the file names as split
191       
192// for editing (unused)
193        Variable/G root:Packages:NIST:VSANS:Event:gStepTolerance = 5            // 5 = # of standard deviations from mean. See PutCursorsAtStep()
194       
195        SetDataFolder root:
196End
197
198
199//
200// the main panel for VSANS Event mode
201// -- a duplicate of the SANS panel, with the functions I'm not using disabled.
202//  could be added back in the future
203//
204Proc VSANS_EventModePanel()
205        Variable sc = 1
206                       
207        if(root:Packages:NIST:VSANS:Globals:gLaptopMode == 1)
208                sc = 0.7
209        endif
210
211        PauseUpdate; Silent 1           // building window...
212        if(root:Packages:NIST:VSANS:Globals:gLaptopMode == 1)
213                NewPanel /W=(82*sc,10*sc,884*sc,590*sc)/N=VSANS_EventModePanel/K=2
214        else
215                NewPanel /W=(82,44,884,664)/N=VSANS_EventModePanel/K=2
216        endif
217       
218        DoWindow/C VSANS_EventModePanel
219        ModifyPanel fixedSize=1,noEdit =1
220
221//      SetDrawLayer UserBack
222//      DrawText 479,345,"Stream Data"
223//      DrawLine 563,338,775,338
224//      DrawText 479,419,"Oscillatory or Stream Data"
225//      DrawLine 647,411,775,411
226
227//      ShowTools/A
228        Button button0,pos={sc*14,70*sc},size={sc*150,20*sc},proc=V_LoadEventLog_Button,title="Load Event Log File"
229        Button button0,fSize=12*sc
230        Button button23,pos={sc*14,100*sc},size={sc*150,20*sc},proc=V_LoadEventLog_Button,title="Load From RAW"
231        Button button23,fSize=12*sc
232        TitleBox tb1,pos={sc*475,450*sc},size={sc*266,86*sc},fSize=10
233        TitleBox tb1,variable= root:Packages:NIST:VSANS:Event:gEventDisplayString
234
235        CheckBox chkbox2,pos={sc*376,151*sc},size={sc*81,15*sc},proc=V_LogIntEvent_Proc,title="Log Intensity"
236        CheckBox chkbox2,fSize=10*sc,variable= root:Packages:NIST:VSANS:Event:gEvent_logint
237        CheckBox chkbox3,pos={sc*14,150*sc},size={sc*119,15*sc},title="Remove Bad Events?",fSize=10*sc
238        CheckBox chkbox3,variable= root:Packages:NIST:VSANS:Event:gRemoveBadEvents
239       
240        Button doneButton,pos={sc*738,36*sc},size={sc*50,20*sc},proc=V_EventDone_Proc,title="Done"
241        Button doneButton,fSize=12*sc
242        Button button6,pos={sc*748,9*sc},size={sc*40,20*sc},proc=V_EventModeHelpButtonProc,title="?"
243
244//      Button button5,pos={sc*633,228*sc},size={sc*140,20*sc},proc=V_ExportSlicesButtonProc,title="Export Slices as VAX",disable=2
245
246        Button button8,pos={sc*570,35*sc},size={sc*120,20*sc},proc=V_CustomBinButtonProc,title="Custom Bins"
247        Button button2,pos={sc*570,65*sc},size={sc*140,20*sc},proc=V_ShowEventDataButtonProc,title="Show Event Data"
248        Button button3,pos={sc*570,95*sc},size={sc*140,20*sc},proc=V_ShowBinDetailsButtonProc,title="Show Bin Details"
249
250                       
251        Button button7,pos={sc*211,33*sc},size={sc*120,20*sc},proc=V_AdjustEventDataButtonProc,title="Adjust Events"
252        Button button4,pos={sc*211,63*sc},size={sc*120,20*sc},proc=V_UndoTimeSortButtonProc,title="Undo Time Sort"
253        Button button18,pos={sc*211,90*sc},size={sc*120,20*sc},proc=V_EC_ImportWavesButtonProc,title="Import Edited"
254       
255        SetVariable setvar0,pos={sc*208,149*sc},size={sc*160,16*sc},proc=V_sliceSelectEvent_Proc,title="Display Time Slice"
256        SetVariable setvar0,fSize=10*sc
257        SetVariable setvar0,limits={0,1000,1},value= root:Packages:NIST:VSANS:Event:gEvent_tsdisp       
258        SetVariable setvar1,pos={sc*389,29*sc},size={sc*160,16*sc},title="Number of slices",fSize=10*sc
259        SetVariable setvar1,limits={1,1000,1},value= root:Packages:NIST:VSANS:Event:gEvent_nslices
260        SetVariable setvar2,pos={sc*389,54*sc},size={sc*160,16*sc},title="Max Time (s)",fSize=10*sc
261        SetVariable setvar2,value= root:Packages:NIST:VSANS:Event:gEvent_t_longest
262       
263        PopupMenu popup0,pos={sc*389,77*sc},size={sc*119,20*sc},proc=V_BinTypePopMenuProc,title="Bin Spacing"
264        PopupMenu popup0,fSize=10*sc
265        PopupMenu popup0,mode=1,popvalue="Equal",value= #"\"Equal;Fibonacci;Custom;\""
266        Button button1,pos={sc*389,103*sc},size={sc*120,20*sc},fSize=12*sc,proc=V_ProcessEventLog_Button,title="Bin Event Data"
267
268// NEW FOR VSANS
269        Button button21,pos={sc*488,205*sc},size={sc*120,20*sc},proc=V_SplitToPanels_Button,title="Split to Panels"
270        Button button22,pos={sc*488,240*sc},size={sc*120,20*sc},proc=V_GraphPanels_Button,title="Show Panels"
271       
272        Button button24,pos={sc*488,270*sc},size={sc*180,20*sc},proc=V_DuplRAWForExport_Button,title="Duplicate RAW for Export"
273        Button button25,pos={sc*488,300*sc},size={sc*180,20*sc},proc=V_CopySlicesForExport_Button,title="Copy Slices for Export"
274        Button button26,pos={sc*488,330*sc},size={sc*180,20*sc},proc=V_SaveExportedNexus_Button,title="Save Exported to Nexus"
275
276//      Button button10,pos={sc*488,305*sc},size={sc*100,20*sc},proc=V_SplitFileButtonProc,title="Split Big File",disable=2
277//      Button button14,pos={sc*488,350*sc},size={sc*120,20*sc},proc=V_Stream_LoadDecim,title="Load Split List",disable=2
278//      Button button19,pos={sc*649,350*sc},size={sc*120,20*sc},proc=V_Stream_LoadAdjustedList,title="Load Edited List",disable=2
279//      Button button20,pos={sc*680,376*sc},size={sc*90,20*sc},proc=V_ShowList_ToLoad,title="Show List",disable=2
280//      SetVariable setvar3,pos={sc*487,378*sc},size={sc*150,16*sc},title="Decimation factor",disable=2
281//      SetVariable setvar3,fSize=10
282//      SetVariable setvar3,limits={1,inf,1},value= root:Packages:NIST:VSANS:Event:gDecimation
283//
284//      Button button15_0,pos={sc*488,425*sc},size={sc*110,20*sc},proc=V_AccumulateSlicesButton,title="Add First Slice",disable=2
285//      Button button16_1,pos={sc*488,450*sc},size={sc*110,20*sc},proc=V_AccumulateSlicesButton,title="Add Next Slice",disable=2
286//      Button button17_2,pos={sc*620,425*sc},size={sc*110,20*sc},proc=V_AccumulateSlicesButton,title="Display Total",disable=2
287
288        CheckBox chkbox1_0,pos={sc*25,30*sc},size={sc*69,14*sc},title="Oscillatory",fSize=10*sc
289        CheckBox chkbox1_0,mode=1,proc=V_EventModeRadioProc,value=0
290        CheckBox chkbox1_1,pos={sc*25,50*sc},size={sc*53,14*sc},title="Stream",fSize=10*sc
291        CheckBox chkbox1_1,proc=V_EventModeRadioProc,value=1,mode=1
292//      CheckBox chkbox1_2,pos={sc*104,59*sc},size={sc*53,14*sc},title="TISANE",fSize=10
293//      CheckBox chkbox1_2,proc=V_EventModeRadioProc,value=0,mode=1
294        CheckBox chkbox1_3,pos={sc*104,30*sc},size={sc*37,14*sc},title="TOF",fSize=10*sc
295        CheckBox chkbox1_3,proc=V_EventModeRadioProc,value=0,mode=1
296       
297        CheckBox chkbox1_4,pos={sc*30,125*sc},size={sc*37,14*sc},title="F",fSize=10*sc
298        CheckBox chkbox1_4,proc=V_EventCarrRadioProc,value=1,mode=1
299        CheckBox chkbox1_5,pos={sc*90,125*sc},size={sc*37,14*sc},title="M",fSize=10*sc
300        CheckBox chkbox1_5,proc=V_EventCarrRadioProc,value=0,mode=1
301       
302        GroupBox group0_0,pos={sc*5,5*sc},size={sc*174,140*sc},title="(1) Loading Mode",fSize=12*sc,fStyle=1
303        GroupBox group0_3,pos={sc*191,5*sc},size={sc*165,130*sc},title="(2) Edit Events",fSize=12*sc,fStyle=1
304        GroupBox group0_1,pos={sc*372,5*sc},size={sc*350,130*sc},title="(3) Bin Events",fSize=12*sc,fStyle=1
305        GroupBox group0_2,pos={sc*477,169*sc},size={sc*310,250*sc},title="(4) View / Export",fSize=12*sc,fStyle=1
306
307//      GroupBox group0_4,pos={sc*474,278*sc},size={sc*312,200*sc},title="Split / Accumulate Files",fSize=12
308//      GroupBox group0_4,fStyle=1
309       
310        Display/W=(10*sc,170*sc,460*sc,610*sc)/HOST=#
311        AppendImage/T/G=1 :Packages:NIST:VSANS:Event:dispsliceData              //  /G=1 flag prevents interpretation as RGB so 3, 4 slices display correctly
312        ModifyImage dispsliceData ctab= {*,*,ColdWarm,0}
313        ModifyImage dispsliceData ctabAutoscale=3
314        ModifyGraph margin(left)=14,margin(bottom)=14,margin(top)=14,margin(right)=14
315        ModifyGraph mirror=2
316        ModifyGraph nticks=4
317        ModifyGraph minor=1
318        ModifyGraph fSize=9
319        ModifyGraph standoff=0
320        ModifyGraph tkLblRot(left)=90
321        ModifyGraph btLen=3
322        ModifyGraph tlOffset=-2
323        RenameWindow #,Event_slicegraph
324        SetActiveSubwindow ##
325EndMacro
326
327
328//
329//
330Function V_DuplRAWForExport_Button(ba) : ButtonControl
331        STRUCT WMButtonAction &ba
332
333        switch( ba.eventCode )
334                case 2: // mouse up
335                        // click code here
336                        V_DuplicateRAWForExport()
337                        //
338                        break
339                case -1: // control being killed
340                        break
341        endswitch
342
343        return 0
344End
345
346
347//
348//
349Function V_CopySlicesForExport_Button(ba) : ButtonControl
350        STRUCT WMButtonAction &ba
351
352        switch( ba.eventCode )
353                case 2: // mouse up
354                        // click code here
355                        String detStr=""
356                        ControlInfo chkbox1_4
357                        if(V_value == 1)
358                                detStr = "F"
359                        else
360                                detStr = "M"
361                        endif
362                        //
363                        V_CopySlicesForExport(detStr)
364                        //
365                        break
366                case -1: // control being killed
367                        break
368        endswitch
369
370        return 0
371End
372
373
374//
375//
376Function V_SaveExportedNexus_Button(ba) : ButtonControl
377        STRUCT WMButtonAction &ba
378
379        switch( ba.eventCode )
380                case 2: // mouse up
381                        // click code here
382                        String detStr=""
383                       
384                        //
385                        Execute "V_SaveExportedEvents()"
386                        //
387                        break
388                case -1: // control being killed
389                        break
390        endswitch
391
392        return 0
393End
394
395
396
397
398
399//
400// takes the event data that is loaded and binned as a combined
401// (192 x 128) panel to the four LRTB panels, each with 48 tubes
402//
403Function V_SplitToPanels_Button(ba) : ButtonControl
404        STRUCT WMButtonAction &ba
405
406        switch( ba.eventCode )
407                case 2: // mouse up
408                        // click code here
409                        V_SplitBinnedToPanels()
410                        //
411                        break
412                case -1: // control being killed
413                        break
414        endswitch
415
416        return 0
417End
418
419
420//
421// after splitting the data into the 4 panels, draws a simple graph to display the panels
422//
423Function V_GraphPanels_Button(ba) : ButtonControl
424        STRUCT WMButtonAction &ba
425
426        switch( ba.eventCode )
427                case 2: // mouse up
428                        // click code here
429                        DoWindow/F VSANS_EventPanels
430                        if(V_flag == 0)
431                                Execute "VSANS_EventPanels()"
432                        endif
433                        //
434                        break
435                case -1: // control being killed
436                        break
437        endswitch
438
439        return 0
440End
441
442
443// mode selector
444//Static Constant MODE_STREAM = 0
445//Static Constant MODE_OSCILL = 1
446//Static Constant MODE_TISANE = 2
447//Static Constant MODE_TOF = 3
448//
449Function V_EventModeRadioProc(name,value)
450        String name
451        Variable value
452       
453        NVAR gEventModeRadioVal= root:Packages:NIST:VSANS:Event:gEvent_mode
454       
455        strswitch (name)
456                case "chkbox1_0":
457                        gEventModeRadioVal= MODE_OSCILL
458                        break
459                case "chkbox1_1":
460                        gEventModeRadioVal= MODE_STREAM
461                        break
462//              case "chkbox1_2":
463//                      gEventModeRadioVal= MODE_TISANE
464//                      break
465                case "chkbox1_3":
466                        gEventModeRadioVal= MODE_TOF
467                        break
468        endswitch
469        CheckBox chkbox1_0,value= gEventModeRadioVal==MODE_OSCILL
470        CheckBox chkbox1_1,value= gEventModeRadioVal==MODE_STREAM
471//      CheckBox chkbox1_2,value= gEventModeRadioVal==MODE_TISANE
472        CheckBox chkbox1_3,value= gEventModeRadioVal==MODE_TOF
473
474        return(0)
475End
476
477Function V_EventCarrRadioProc(name,value)
478        String name
479        Variable value
480               
481        strswitch (name)
482                case "chkbox1_4":
483                        CheckBox chkbox1_4,value= 1
484                        CheckBox chkbox1_5,value= 0
485                        break
486                case "chkbox1_5":
487                        CheckBox chkbox1_4,value= 0
488                        CheckBox chkbox1_5,value= 1
489                        break
490        endswitch
491
492        return(0)
493End
494
495
496Function V_AdjustEventDataButtonProc(ba) : ButtonControl
497        STRUCT WMButtonAction &ba
498
499        switch( ba.eventCode )
500                case 2: // mouse up
501                        // click code here
502                        Execute "V_ShowEventCorrectionPanel()"
503                        //
504                        break
505                case -1: // control being killed
506                        break
507        endswitch
508
509        return 0
510End
511
512Function V_CustomBinButtonProc(ba) : ButtonControl
513        STRUCT WMButtonAction &ba
514
515        switch( ba.eventCode )
516                case 2: // mouse up
517                        // click code here
518                        Execute "V_Show_CustomBinPanel()"
519                        //
520                        break
521                case -1: // control being killed
522                        break
523        endswitch
524
525        return 0
526End
527
528
529Function V_ShowEventDataButtonProc(ba) : ButtonControl
530        STRUCT WMButtonAction &ba
531
532        switch( ba.eventCode )
533                case 2: // mouse up
534                        // click code here
535                        v_tic()
536                        printf "Show rescaled time graph = "
537                        Execute "V_ShowRescaledTimeGraph()"
538                        v_toc()
539                        //
540                        v_tic()
541                        printf "calculate and show differential = "
542                        V_DifferentiatedTime()
543                        v_toc()
544                        //
545                        break
546                case -1: // control being killed
547                        break
548        endswitch
549
550        return 0
551End
552
553Function V_BinTypePopMenuProc(pa) : PopupMenuControl
554        STRUCT WMPopupAction &pa
555
556        switch( pa.eventCode )
557                case 2: // mouse up
558                        Variable popNum = pa.popNum
559                        String popStr = pa.popStr
560                        if(cmpstr(popStr,"Custom")==0)
561                                Execute "V_Show_CustomBinPanel()"
562                        endif
563                        break
564                case -1: // control being killed
565                        break
566        endswitch
567
568        return 0
569End
570
571Function V_ShowBinDetailsButtonProc(ba) : ButtonControl
572        STRUCT WMButtonAction &ba
573
574        switch( ba.eventCode )
575                case 2: // mouse up
576                        // click code here
577                        Execute "V_ShowBinTable()"
578                        Execute "V_BinEventBarGraph()"
579                        break
580                case -1: // control being killed
581                        break
582        endswitch
583
584        return 0
585End
586
587Function V_UndoTimeSortButtonProc(ba) : ButtonControl
588        STRUCT WMButtonAction &ba
589
590        switch( ba.eventCode )
591                case 2: // mouse up
592                        // click code here
593                        Execute "V_UndoTheSorting()"
594                        break
595                case -1: // control being killed
596                        break
597        endswitch
598
599        return 0
600End
601
602Function V_ExportSlicesButtonProc(ba) : ButtonControl
603        STRUCT WMButtonAction &ba
604
605        switch( ba.eventCode )
606                case 2: // mouse up
607                        // click code here
608                        Execute "V_ExportSlicesAsVAX()"         //will invoke the dialog
609                        break
610                case -1: // control being killed
611                        break
612        endswitch
613
614        return 0
615End
616
617Function V_EventModeHelpButtonProc(ba) : ButtonControl
618        STRUCT WMButtonAction &ba
619
620        switch( ba.eventCode )
621                case 2: // mouse up
622                        // click code here
623                        DisplayHelpTopic/Z "VSANS Event Mode Data"
624                        break
625                case -1: // control being killed
626                        break
627        endswitch
628
629        return 0
630End
631
632
633Function V_EventDone_Proc(ba) : ButtonControl
634        STRUCT WMButtonAction &ba
635       
636        String win = ba.win
637        switch (ba.eventCode)
638                case 2:
639                        DoWindow/K VSANS_EventModePanel
640                        break
641        endswitch
642        return(0)
643End
644
645
646
647Function V_ProcessEventLog_Button(ctrlName) : ButtonControl
648        String ctrlName
649       
650        NVAR mode=root:Packages:NIST:VSANS:Event:gEvent_Mode
651       
652        if(mode == MODE_STREAM)
653                V_Stream_ProcessEventLog("")
654        endif
655       
656        if(mode == MODE_OSCILL)
657                V_Osc_ProcessEventLog("")
658        endif
659       
660        // If TOF mode, process as Oscillatory -- that is, take the times as is
661        if(mode == MODE_TOF)
662                V_Osc_ProcessEventLog("")
663        endif
664       
665        // toggle the checkbox for log display to force the display to be correct
666        NVAR gLog = root:Packages:NIST:VSANS:Event:gEvent_logint
667        V_LogIntEvent_Proc("",gLog)
668       
669        return(0)
670end
671
672//
673// for oscillatory mode
674//
675// Allocate the space for the data as if it was a single 192 x 128 pixel array.
676// The (4) 48-tube panels will be split out later. this means that as defined,
677// XBINS is for an individual panel
678// NTUBES is the total number of tubes = (4)(48)=192
679//
680Function V_Osc_ProcessEventLog(ctrlName)
681        String ctrlName
682
683//      Make/O/D/N=(XBINS,YBINS) root:Packages:NIST:VSANS:Event:binnedData
684        Make/O/D/N=(NTUBES,YBINS) root:Packages:NIST:VSANS:Event:binnedData
685       
686        Wave binnedData = root:Packages:NIST:VSANS:Event:binnedData
687        Wave xLoc = root:Packages:NIST:VSANS:Event:xLoc
688        Wave yLoc = root:Packages:NIST:VSANS:Event:yLoc
689
690// now with the number of slices and max time, process the events
691
692        NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
693        NVAR nslices = root:Packages:NIST:VSANS:Event:gEvent_nslices
694
695        SetDataFolder root:Packages:NIST:VSANS:Event            //don't count on the folder remaining here
696       
697//      Make/D/O/N=(XBINS,YBINS,nslices) slicedData
698        Make/D/O/N=(NTUBES,YBINS,nslices) slicedData
699               
700        Wave slicedData = slicedData
701        Wave rescaledTime = rescaledTime
702        Wave timePt = timePt
703//      Make/O/D/N=(XBINS,YBINS) tmpData
704        Make/O/D/N=(NTUBES,YBINS) tmpData
705        Make/O/D/N=(nslices+1) binEndTime,binCount
706        Make/O/D/N=(nslices) timeWidth
707        Wave timeWidth = timeWidth
708        Wave binEndTime = binEndTime
709        Wave binCount = binCount
710
711        variable ii,del,p1,p2,t1,t2
712        del = t_longest/nslices
713
714        slicedData = 0
715        binEndTime[0]=0
716        BinCount[nslices]=0
717
718
719        String binTypeStr=""
720        ControlInfo /W=VSANS_EventModePanel popup0
721        binTypeStr = S_value
722       
723        strswitch(binTypeStr)   // string switch
724                case "Equal":           // execute if case matches expression
725                        V_SetLinearBins(binEndTime,timeWidth,nslices,t_longest)
726                        break                                           // exit from switch
727                case "Fibonacci":               // execute if case matches expression
728                        V_SetFibonacciBins(binEndTime,timeWidth,nslices,t_longest)
729                        break
730                case "Log":             // execute if case matches expression
731                        V_SetLogBins(binEndTime,timeWidth,nslices,t_longest)
732                        break
733                case "Custom":          // execute if case matches expression
734                        //bins are set by the user on the panel - assume it's good to go
735                        break
736                default:                                                        // optional default expression executed
737                        DoAlert 0,"No match for bin type, Equal bins used"
738                        V_SetLinearBins(binEndTime,timeWidth,nslices,t_longest)
739        endswitch
740
741
742// now before binning, sort the data
743
744        //this is slow - undoing the sorting and starting over, but if you don't,
745        // you'll never be able to undo the sort
746        //
747        SetDataFolder root:Packages:NIST:VSANS:Event:
748
749v_tic()
750        if(WaveExists($"root:Packages:NIST:VSANS:Event:OscSortIndex") == 0 )
751                Duplicate/O rescaledTime OscSortIndex
752                MakeIndex rescaledTime OscSortIndex
753                IndexSort OscSortIndex, yLoc,xLoc,timePt,rescaledTime   
754                //SetDataFolder root:Packages:NIST:VSANS:Event
755                V_IndexForHistogram(xLoc,yLoc,binnedData)                       // index the events AFTER sorting
756                //SetDataFolder root:
757        Endif
758       
759printf "sort time = "
760v_toc()
761
762        Wave index = root:Packages:NIST:VSANS:Event:SavedIndex          //this is the histogram index
763
764v_tic()
765        for(ii=0;ii<nslices;ii+=1)
766                if(ii==0)
767//                      t1 = ii*del
768//                      t2 = (ii+1)*del
769                        p1 = BinarySearch(rescaledTime,0)
770                        p2 = BinarySearch(rescaledTime,binEndTime[ii+1])
771                else
772//                      t2 = (ii+1)*del
773                        p1 = p2+1               //one more than the old one
774                        p2 = BinarySearch(rescaledTime,binEndTime[ii+1])               
775                endif
776
777        // typically zero will never be a valid time value in oscillatory mode. in "stream" mode, the first is normalized to == 0
778        // but not here - times are what they are.
779                if(p1 == -1)
780                        Printf "p1 = -1 Binary search off the end %15.10g <?? %15.10g\r", 0, rescaledTime[0]
781                        p1 = 0          //set to the first point if it's off the end
782                Endif
783               
784                if(p2 == -2)
785                        Printf "p2 = -2 Binary search off the end %15.10g >?? %15.10g\r", binEndTime[ii+1], rescaledTime[numpnts(rescaledTime)-1]
786                        p2 = numpnts(rescaledTime)-1            //set to the last point if it's off the end
787                Endif
788//              Print p1,p2
789
790
791                tmpData=0
792                V_JointHistogramWithRange(xLoc,yLoc,tmpData,index,p1,p2)
793                slicedData[][][ii] = tmpData[p][q]
794               
795//              binEndTime[ii+1] = t2
796                binCount[ii] = sum(tmpData,-inf,inf)
797        endfor
798printf "histogram time = "
799v_toc()
800
801        Duplicate/O slicedData,root:Packages:NIST:VSANS:Event:dispsliceData,root:Packages:NIST:VSANS:Event:logSlicedData
802        Wave logSlicedData = root:Packages:NIST:VSANS:Event:logSlicedData
803        logslicedData = log(slicedData)
804
805        SetDataFolder root:
806        return(0)
807End
808
809// for a "continuous exposure"
810//
811// if there is a sort of these events, I need to re-index the events for the histogram
812// - see the oscillatory mode  - and sort the events here, then immediately re-index for the histogram
813// - but with the added complication that I need to always remember to index for the histogram, every time
814// - since I don't know if I've sorted or un-sorted. Osc mode always forces a re-sort and a re-index
815//
816//
817// Allocate the space for the data as if it was a single 192 x 128 pixel array.
818// The (4) 48-tube panels will be split out later. this means that as defined,
819// XBINS is for an individual panel
820// NTUBES is the total number of tubes = (4)(48)=192
821//
822Function V_Stream_ProcessEventLog(ctrlName)
823        String ctrlName
824
825//      NVAR slicewidth = root:Packages:NIST:gTISANE_slicewidth
826
827       
828//      Make/O/D/N=(XBINS,YBINS) root:Packages:NIST:VSANS:Event:binnedData
829        Make/O/D/N=(NTUBES,YBINS) root:Packages:NIST:VSANS:Event:binnedData
830       
831        Wave binnedData = root:Packages:NIST:VSANS:Event:binnedData
832        Wave xLoc = root:Packages:NIST:VSANS:Event:xLoc
833        Wave yLoc = root:Packages:NIST:VSANS:Event:yLoc
834
835// now with the number of slices and max time, process the events
836
837        NVAR yesSortStream = root:Packages:NIST:VSANS:Event:gSortStreamEvents           //do I sort the events?
838        NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
839        NVAR nslices = root:Packages:NIST:VSANS:Event:gEvent_nslices
840
841        SetDataFolder root:Packages:NIST:VSANS:Event            //don't count on the folder remaining here
842       
843//      Make/D/O/N=(XBINS,YBINS,nslices) slicedData
844        Make/D/O/N=(NTUBES,YBINS,nslices) slicedData
845               
846        Wave slicedData = slicedData
847        Wave rescaledTime = rescaledTime
848//      Make/O/D/N=(XBINS,YBINS) tmpData
849        Make/O/D/N=(NTUBES,YBINS) tmpData
850        Make/O/D/N=(nslices+1) binEndTime,binCount//,binStartTime
851        Make/O/D/N=(nslices) timeWidth
852        Wave binEndTime = binEndTime
853        Wave timeWidth = timeWidth
854        Wave binCount = binCount
855
856        variable ii,del,p1,p2,t1,t2
857        del = t_longest/nslices
858
859        slicedData = 0
860        binEndTime[0]=0
861        BinCount[nslices]=0
862       
863        String binTypeStr=""
864        ControlInfo /W=VSANS_EventModePanel popup0
865        binTypeStr = S_value
866       
867        strswitch(binTypeStr)   // string switch
868                case "Equal":           // execute if case matches expression
869                        V_SetLinearBins(binEndTime,timeWidth,nslices,t_longest)
870                        break                                           // exit from switch
871                case "Fibonacci":               // execute if case matches expression
872                        V_SetFibonacciBins(binEndTime,timeWidth,nslices,t_longest)
873                        break
874                case "Log":             // execute if case matches expression
875                        V_SetLogBins(binEndTime,timeWidth,nslices,t_longest)
876                        break
877                case "Custom":          // execute if case matches expression
878                        //bins are set by the user on the panel - assume it's good to go
879                        break
880                default:                                                        // optional default expression executed
881                        DoAlert 0,"No match for bin type, Equal bins used"
882                        V_SetLinearBins(binEndTime,timeWidth,nslices,t_longest)
883        endswitch
884
885// TODO
886// the global exists for this switch, but it is not implemented - not sure whether
887// it's correct to implement this at all --
888//
889        if(yesSortStream == 1)
890                V_SortTimeData()
891        endif
892       
893// index the events before binning
894// if there is a sort of these events, I need to re-index the events for the histogram
895//      SetDataFolder root:Packages:NIST:VSANS:Event
896        V_IndexForHistogram(xLoc,yLoc,binnedData)
897//      SetDataFolder root:
898        Wave index = root:Packages:NIST:VSANS:Event:SavedIndex          //the index for the histogram
899       
900       
901        for(ii=0;ii<nslices;ii+=1)
902                if(ii==0)
903//                      t1 = ii*del
904//                      t2 = (ii+1)*del
905                        p1 = BinarySearch(rescaledTime,0)
906                        p2 = BinarySearch(rescaledTime,binEndTime[ii+1])
907                else
908//                      t2 = (ii+1)*del
909                        p1 = p2+1               //one more than the old one
910                        p2 = BinarySearch(rescaledTime,binEndTime[ii+1])               
911                endif
912
913                if(p1 == -1)
914                        Printf "p1 = -1 Binary search off the end %15.10g <?? %15.10g\r", 0, rescaledTime[0]
915                        p1 = 0          //set to the first point if it's off the end
916                Endif
917                if(p2 == -2)
918                        Printf "p2 = -2 Binary search off the end %15.10g >?? %15.10g\r", binEndTime[ii+1], rescaledTime[numpnts(rescaledTime)-1]
919                        p2 = numpnts(rescaledTime)-1            //set to the last point if it's off the end
920                Endif
921//              Print p1,p2
922
923
924                tmpData=0
925                V_JointHistogramWithRange(xLoc,yLoc,tmpData,index,p1,p2)
926                slicedData[][][ii] = tmpData[p][q]
927               
928//              binEndTime[ii+1] = t2
929                binCount[ii] = sum(tmpData,-inf,inf)
930        endfor
931
932        Duplicate/O slicedData,root:Packages:NIST:VSANS:Event:dispsliceData,root:Packages:NIST:VSANS:Event:logSlicedData
933        Wave logSlicedData = root:Packages:NIST:VSANS:Event:logSlicedData
934        logslicedData = log(slicedData)
935
936        SetDataFolder root:
937        return(0)
938End
939
940
941Proc    V_UndoTheSorting()
942        V_Osc_UndoSort()
943End
944
945// for oscillatory mode
946//
947// -- this takes the previously generated index, and un-sorts the data to restore to the
948// "as-collected" state
949//
950Function V_Osc_UndoSort()
951
952        SetDataFolder root:Packages:NIST:VSANS:Event            //don't count on the folder remaining here
953        Wave rescaledTime = rescaledTime
954        Wave OscSortIndex = OscSortIndex
955        Wave yLoc = yLoc
956        Wave xLoc = xLoc
957        Wave timePt = timePt
958
959        Sort OscSortIndex OscSortIndex,yLoc,xLoc,timePt,rescaledTime
960
961        KillWaves/Z OscSortIndex
962       
963        SetDataFolder root:
964        return(0)
965End
966
967
968// now before binning, sort the data
969//
970//this is slow - undoing the sorting and starting over, but if you don't,
971// you'll never be able to undo the sort
972//
973Function V_SortTimeData()
974
975
976        SetDataFolder root:Packages:NIST:VSANS:Event:
977
978        KillWaves/Z OscSortIndex
979       
980        if(WaveExists($"root:Packages:NIST:VSANS:Event:OscSortIndex") == 0 )
981                Duplicate/O rescaledTime OscSortIndex
982                MakeIndex rescaledTime OscSortIndex
983                IndexSort OscSortIndex, yLoc,xLoc,timePt,rescaledTime   
984        Endif
985       
986        SetDataFolder root:
987        return(0)
988End
989
990
991
992Function V_SetLinearBins(binEndTime,timeWidth,nslices,t_longest)
993        Wave binEndTime,timeWidth
994        Variable nslices,t_longest
995
996        Variable del,ii,t2
997        binEndTime[0]=0         //so the bar graph plots right...
998        del = t_longest/nslices
999       
1000        for(ii=0;ii<nslices;ii+=1)
1001                t2 = (ii+1)*del
1002                binEndTime[ii+1] = t2
1003        endfor
1004        binEndTime[ii+1] = t_longest*(1-1e-6)           //otherwise floating point errors such that the last time point is off the end of the Binary search
1005
1006        timeWidth = binEndTime[p+1]-binEndTime[p]
1007
1008        return(0)       
1009End
1010
1011
1012// TODO
1013// either get this to work, or scrap it entirely. it currently isn't on the popup
1014// so it can't be accessed
1015Function V_SetLogBins(binEndTime,timeWidth,nslices,t_longest)
1016        Wave binEndTime,timeWidth
1017        Variable nslices,t_longest
1018
1019        Variable tMin,ii
1020
1021        Wave rescaledTime = root:Packages:NIST:VSANS:Event:rescaledTime
1022       
1023        binEndTime[0]=0         //so the bar graph plots right...
1024
1025        // just like the log-scaled q-points
1026        tMin = rescaledTime[1]/1                        //just a guess... can't use tMin=0, and rescaledTime[0] == 0 by definition
1027        Print rescaledTime[1], tMin
1028        for(ii=0;ii<nslices;ii+=1)
1029                binEndTime[ii+1] =alog(log(tMin) + (ii+1)*((log(t_longest)-log(tMin))/nslices))
1030        endfor
1031        binEndTime[ii+1] = t_longest            //otherwise floating point errors such that the last time point is off the end of the Binary search
1032       
1033        timeWidth = binEndTime[p+1]-binEndTime[p]
1034
1035        return(0)
1036End
1037
1038Function V_MakeFibonacciWave(w,num)
1039        Wave w
1040        Variable num
1041
1042        //skip the initial zero
1043        Variable f1,f2,ii
1044        f1=1
1045        f2=1
1046        w[0] = f1
1047        w[1] = f2
1048        for(ii=2;ii<num;ii+=1)
1049                w[ii] = f1+f2
1050                f1=f2
1051                f2=w[ii]
1052        endfor
1053               
1054        return(0)
1055end
1056
1057Function V_SetFibonacciBins(binEndTime,timeWidth,nslices,t_longest)
1058        Wave binEndTime,timeWidth
1059        Variable nslices,t_longest
1060
1061        Variable tMin,ii,total,t2,tmp
1062        Make/O/D/N=(nslices) fibo
1063        fibo=0
1064        V_MakeFibonacciWave(fibo,nslices)
1065       
1066//      Make/O/D tmpFib={1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946}
1067
1068        binEndTime[0]=0         //so the bar graph plots right...
1069        total = sum(fibo,0,nslices-1)           //total number of "pieces"
1070       
1071        tmp=0
1072        for(ii=0;ii<nslices;ii+=1)
1073                t2 = sum(fibo,0,ii)/total*t_longest
1074                binEndTime[ii+1] = t2
1075        endfor
1076        binEndTime[ii+1] = t_longest            //otherwise floating point errors such that the last time point is off the end of the Binary search
1077       
1078        timeWidth = binEndTime[p+1]-binEndTime[p]
1079       
1080        return(0)
1081End
1082
1083
1084
1085//
1086// -- The "file too large" check has currently been set to 1.5 GB
1087//
1088//     
1089Function V_LoadEventLog_Button(ctrlName) : ButtonControl
1090        String ctrlName
1091
1092        NVAR mode=root:Packages:NIST:VSANS:Event:gEvent_mode
1093        Variable err=0
1094        Variable fileref,totBytes
1095        NVAR fileTooLarge = root:Packages:NIST:VSANS:Event:gEventFileTooLarge           //limit load to 1500MB
1096
1097        SVAR filename = root:Packages:NIST:VSANS:Event:gEvent_logfile
1098        NVAR nslices = root:Packages:NIST:VSANS:Event:gEvent_nslices
1099        NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
1100       
1101        String fileFilters = "All Files:.*;Data Files (*.txt):.txt;"
1102        String abortStr
1103       
1104        PathInfo catPathName
1105        if(V_flag==0)
1106                DoAlert 0,"Please 'Pick Path' to the data from the Main (yellow) Panel."
1107                return(0)
1108        endif
1109       
1110        // load from raw?
1111        // if so, which carriage?
1112        String loadFromRAW="No"
1113        String detStr
1114        if(cmpstr(ctrlName,"button23")==0)
1115                loadFromRAW = "Yes"
1116                ControlInfo chkbox1_4
1117                if(V_value == 1)
1118                        detStr = "F"
1119                else
1120                        detStr = "M"
1121                endif           
1122        endif
1123       
1124//      Prompt loadFromRAW,"Load from RAW?",popup,"Yes;No;"
1125//      Prompt detStr,"Carriage",popup,"M;F;"
1126//      DoPrompt "Load data from...",loadFromRAW,detStr
1127       
1128//      if(V_flag)              //user cancel
1129//              return(0)
1130//      endif
1131       
1132        if(cmpstr(loadFromRAW,"Yes")==0)
1133                PathInfo catPathName
1134                filename = S_Path + V_getDetEventFileName("RAW",detStr+"L")
1135               
1136                // check here to see if the file can be found. if not report the error and exit
1137                Open/R/Z=1 fileref as fileName
1138                if(V_flag == 0)
1139                        Close fileref
1140                else
1141                        DoAlert 0,"The event file associated with RAW cannot be found.       "+filename
1142                        return(0)
1143                endif
1144        else
1145                Open/R/D/P=catPathName/F=fileFilters fileref
1146                filename = S_filename
1147                if(strlen(S_filename) == 0)
1148                        // user cancelled
1149                        DoAlert 0,"No file selected, no file loaded."
1150                        return(1)
1151                endif
1152        endif
1153//  keep this   , but set to 1.5 GB
1154// since I'm now in 64-bit space
1155/// Abort if the files are too large
1156        Open/R fileref as fileName
1157                FStatus fileref
1158        Close fileref
1159//
1160        totBytes = V_logEOF/1e6         //in MB
1161        if(totBytes > fileTooLarge)
1162                sprintf abortStr,"File is %g MB, larger than the limit of %g MB. Split and Decimate.",totBytes,fileTooLarge
1163                Abort abortStr
1164        endif
1165//     
1166        Print "TotalBytes (MB) = ",totBytes
1167       
1168
1169Variable t1 = ticks
1170        SetDataFolder root:Packages:NIST:VSANS:Event:
1171
1172// load in the event file and decode it
1173       
1174//      V_readFakeEventFile(fileName)
1175        V_LoadEvents()                  // this now loads, decodes, and returns location, tube, and timePt
1176        SetDataFolder root:Packages:NIST:VSANS:Event:                   //GBLoadWave in V_LoadEvents sets back to root:
1177
1178// Now, I have tube, location, and timePt (no units yet)
1179// assign to the proper panels
1180
1181//
1182// x- (YES - this is MUCH faster)  if I do the JointHistogram first, then break out the blocks of the
1183//  3D sliced data into the individual panels. Then the sort operation can be skipped,
1184//  since it is implicitly be done during the histogram operation
1185// x- go back and redimension as needed to get the 128 x 192 histogram to work
1186// x- MatrixOp or a wave assignemt should be able to break up the 3D
1187//
1188
1189                KillWaves/Z timePt,xLoc,yLoc
1190                Duplicate/O eventTime timePt
1191
1192//
1193// x- for processing, initially treat all of the tubes along x, and 128 pixels along y
1194//   panels can be transposed later as needed to get the orientation correct
1195
1196                Duplicate/O tube xLoc
1197                Duplicate/O location yLoc
1198               
1199                Redimension/D xLoc,yLoc,timePt 
1200               
1201//v_tic()
1202//      V_SortAndSplitEvents()
1203//
1204//Printf "File sort and split time (s) = "
1205//v_toc()
1206
1207//
1208// switch the "active" panel to the selected group (1-4) (5 concatenates them all together)
1209//
1210// copy the set of tubes over to the "active" set that is to be histogrammed
1211// and redimension them to be sure that they are double precision
1212//
1213//
1214//      V_SwitchTubeGroup(1)
1215//
1216//     
1217
1218
1219        Wave timePt=timePt
1220        Wave xLoc=xLoc
1221        Wave yLoc=yLoc
1222        V_CleanupTimes(xLoc,yLoc,timePt)                //remove zeroes
1223       
1224        NVAR gResol = root:Packages:NIST:VSANS:Event:gResol             //timeStep in clock frequency (Hz)
1225        Printf "Time Step = 1/Frequency (ns) = %g\r",(1/gResol)*1e9
1226        variable timeStep_s = (1/gResol)
1227
1228// DONE:
1229//  x- the time scaling is done.
1230// TODO: VERIFY
1231// ??? timeStep from the clock frequency is not right--- the step appears to be 100 ns???
1232//     
1233        timeStep_s = 100e-9
1234       
1235/////
1236// now do a little processing of the times based on the type of data
1237//     
1238
1239
1240
1241        if(mode == MODE_STREAM)         // continuous "Stream" mode - start from zero
1242                v_tic()
1243                printf "Duplicate wave = "
1244                        KillWaves/Z rescaledTime
1245                        Duplicate/O timePt rescaledTime
1246                v_toc()
1247                v_tic()
1248                printf "rescale time = "
1249        //              rescaledTime = 1*(timePt-timePt[0])             //convert to nanoseconds and start from zero
1250                        rescaledTime = timeStep_s*(timePt-timePt[0])            //convert to seconds and start from zero
1251                v_toc()
1252                v_tic()
1253                printf "find wave Max = "
1254                        t_longest = waveMax(rescaledTime)               //should be the last point     
1255                v_toc()
1256        endif
1257
1258       
1259        if(mode == MODE_OSCILL)         // oscillatory mode - don't adjust the times, we get periodic t0 to reset t=0
1260                KillWaves/Z rescaledTime
1261                Duplicate/O timePt rescaledTime
1262                rescaledTime *= timeStep_s                      //convert to seconds and that's all
1263                t_longest = waveMax(rescaledTime)               //if oscillatory, won't be the last point, so get it this way
1264       
1265                KillWaves/Z OscSortIndex                        //to make sure that there is no old index hanging around
1266        endif
1267
1268// MODE_TISANE
1269
1270
1271// MODE_TOF
1272        if(mode == MODE_TOF)            // TOF mode - don't adjust the times, we get periodic t0 to reset t=0
1273                KillWaves/Z rescaledTime
1274                Duplicate/O timePt rescaledTime
1275                rescaledTime *= timeStep_s              //convert to seconds and that's all
1276                t_longest = waveMax(rescaledTime)               //if oscillatory, won't be the last point, so get it this way
1277       
1278                KillWaves/Z OscSortIndex                        //to make sure that there is no old index hanging around
1279        endif
1280
1281        SetDataFolder root:
1282
1283Variable t2 = ticks
1284
1285        STRUCT WMButtonAction ba
1286        ba.eventCode = 2
1287        V_ShowEventDataButtonProc(ba)
1288
1289Variable t3 = ticks
1290
1291        Print "load and process (s) = ",(t2-t1)/60.15
1292        Print "Overall including graphs (s) = ",(t3-t1)/60.15
1293        return(0)
1294End
1295
1296
1297
1298
1299//
1300// -- MUCH faster to count the number of lines to remove, then delete (N)
1301// rather then delete them one-by-one in the do-loop
1302//
1303Function V_CleanupTimes(xLoc,yLoc,timePt)
1304        Wave xLoc,yLoc,timePt
1305
1306        // start at the back and remove zeros
1307        Variable num=numpnts(xLoc),ii,numToRemove
1308
1309        numToRemove = 0
1310        ii=num
1311        do
1312                ii -= 1
1313                if(timePt[ii] == 0 && xLoc[ii] == 0 && yLoc[ii] == 0)
1314                        numToRemove += 1
1315                endif
1316        while(timePt[ii-1] == 0 && xLoc[ii-1] == 0 && yLoc[ii-1] == 0)
1317       
1318        if(numToRemove != 0)
1319                DeletePoints ii, numToRemove, xLoc,yLoc,timePt
1320        endif
1321       
1322        return(0)
1323End
1324
1325Function V_LogIntEvent_Proc(ctrlName,checked) : CheckBoxControl
1326        String ctrlName
1327        Variable checked
1328               
1329        SetDataFolder root:Packages:NIST:VSANS:Event
1330       
1331        Wave slicedData = slicedData
1332        Wave logSlicedData = logSlicedData
1333        Wave dispSliceData = dispSliceData
1334       
1335        if(checked)
1336                logslicedData = log(slicedData)
1337                Duplicate/O logslicedData dispsliceData
1338        else
1339                Duplicate/O slicedData dispsliceData
1340        endif
1341
1342        NVAR selectedslice = root:Packages:NIST:VSANS:Event:gEvent_tsdisp
1343
1344        V_sliceSelectEvent_Proc("", selectedslice, "", "")
1345
1346        SetDataFolder root:
1347
1348End
1349
1350
1351// (DONE)
1352// this "fails" for data sets that have 3 or 4 slices, as the ModifyImage command
1353// interprets the data as being RGB - and so does nothing.
1354// need to find a way around this
1355//
1356////  When first plotted, AppendImage/G=1 flag prevents interpretation as RGB so 3, 4 slices display correctly
1357///
1358// I could modify this procedure to use the log = 0|1 keyword for the log Z display
1359// rather than creating a duplicate wave of log(data)
1360//
1361Function V_sliceSelectEvent_Proc(ctrlName, varNum, varStr, varName) : SetVariableControl
1362        String ctrlName
1363        Variable varNum
1364        String varStr
1365        String varName
1366       
1367        NVAR nslices = root:Packages:NIST:VSANS:Event:gEvent_nslices
1368        NVAR selectedslice = root:Packages:NIST:VSANS:Event:gEvent_tsdisp
1369       
1370        if(varNum < 0)
1371                selectedslice = 0
1372                DoUpdate
1373        elseif (varNum > nslices-1)
1374                selectedslice = nslices-1
1375                DoUpdate
1376        else
1377                ModifyImage/W=VSANS_EventModePanel#Event_slicegraph ''#0 plane = varNum
1378        endif
1379
1380End
1381
1382Function V_DifferentiatedTime()
1383
1384        Wave rescaledTime = root:Packages:NIST:VSANS:Event:rescaledTime
1385
1386        SetDataFolder root:Packages:NIST:VSANS:Event:
1387               
1388        Differentiate rescaledTime/D=rescaledTime_DIF
1389//      Display rescaledTime,rescaledTime_DIF
1390        DoWindow/F V_Differentiated_Time
1391        if(V_flag == 0)
1392                Display/N=V_Differentiated_Time/K=1 rescaledTime_DIF
1393                Legend
1394                Modifygraph gaps=0
1395                ModifyGraph zero(left)=1
1396                Label left "\\Z14Delta (dt/event)"
1397                Label bottom "\\Z14Event number"
1398        endif
1399       
1400        SetDataFolder root:
1401       
1402        return(0)
1403End
1404
1405
1406//
1407// for the bit shifts, see the decimal-binary conversion
1408// http://www.binaryconvert.com/convert_unsigned_int.html
1409//
1410//  for 64-bit values:
1411// http://calc.penjee.com
1412//
1413//
1414//
1415//              K0 = 536870912
1416//              Print (K0 & 0x08000000)/134217728       //bit 27 only, shift by 2^27
1417//              Print (K0 & 0x10000000)/268435456               //bit 28 only, shift by 2^28
1418//              Print (K0 & 0x20000000)/536870912               //bit 29 only, shift by 2^29
1419//
1420//
1421//
1422// This function loads the events, and decodes them.
1423// Assigning them to detector panels is a separate function
1424//
1425//
1426//
1427Function V_LoadEvents()
1428       
1429        NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
1430       
1431        SVAR filepathstr = root:Packages:NIST:VSANS:Event:gEvent_logfile
1432        SVAR dispStr = root:Packages:NIST:VSANS:Event:gEventDisplayString
1433       
1434        SetDataFolder root:Packages:NIST:VSANS:Event
1435
1436        Variable refnum
1437        String buffer
1438        String fileStr,tmpStr
1439        Variable verbose
1440        Variable xval,yval
1441        Variable numXYevents,totBytes
1442
1443//  to read a VSANS event file:
1444//
1445// - get the file name
1446//      - read the header (all of it, since I need parts of it) (maybe read as a struct? but I don't know the size!)
1447// - move to EOF and close
1448//
1449// - Use GBLoadWave to read the 64-bit events in
1450
1451
1452/// globals to report the header back for use or status
1453        SVAR gVSANSStr = root:Packages:NIST:VSANS:Event:gVsansStr
1454        NVAR gRevision = root:Packages:NIST:VSANS:Event:gRevision
1455        NVAR gOffset = root:Packages:NIST:VSANS:Event:gOffset           // = 22 bytes if no disabled tubes
1456        NVAR gTime1 = root:Packages:NIST:VSANS:Event:gTime1
1457        NVAR gTime2 = root:Packages:NIST:VSANS:Event:gTime2
1458        NVAR gTime3 = root:Packages:NIST:VSANS:Event:gTime3
1459        NVAR gTime4 = root:Packages:NIST:VSANS:Event:gTime4     // these 4 time pieces are supposed to be 8 bytes total
1460        NVAR gTime5 = root:Packages:NIST:VSANS:Event:gTime5     // these 5 time pieces are supposed to be 10 bytes total
1461        SVAR gDetStr = root:Packages:NIST:VSANS:Event:gDetStr
1462        NVAR gVolt = root:Packages:NIST:VSANS:Event:gVolt
1463        NVAR gResol = root:Packages:NIST:VSANS:Event:gResol             //time resolution in nanoseconds
1464/////
1465
1466        gVSANSStr = PadString(gVSANSStr,5,0x20)         //pad to 5 bytes
1467        gDetStr = PadString(gDetStr,1,0x20)                             //pad to 1 byte
1468
1469        numXYevents = 0
1470
1471
1472        Open/R refnum as filepathstr
1473       
1474v_tic()
1475
1476        FBinRead refnum, gVSANSStr
1477        FBinRead/F=2/U refnum, gRevision
1478        FBinRead/F=2/U refnum, gOffset
1479        FBinRead/F=2/U refnum, gTime1
1480        FBinRead/F=2/U refnum, gTime2
1481        FBinRead/F=2/U refnum, gTime3
1482        FBinRead/F=2/U refnum, gTime4
1483        FBinRead/F=2/U refnum, gTime5
1484        FBinRead refnum, gDetStr
1485        FBinRead/F=2/U refnum, gVolt
1486        FBinRead/F=3/U refnum, gResol
1487
1488        FStatus refnum
1489        FSetPos refnum, V_logEOF
1490       
1491        Close refnum
1492       
1493// number of data bytes
1494        numXYevents = (V_logEOF-gOffset)/8
1495        Print "Number of data values = ",numXYevents
1496       
1497        GBLoadWave/B/T={192,192}/W=1/S=(gOffset) filepathstr
1498       
1499        Duplicate/O $(StringFromList(0,S_waveNames)) V_Events
1500        KillWaves/Z $(StringFromList(0,S_waveNames))
1501
1502Printf "Time to read file (s) = "
1503v_toc()
1504
1505
1506        totBytes = V_logEOF
1507        Print "total bytes = ", totBytes
1508       
1509
1510// V_Events is the uint64 wave that was read in
1511//
1512////// Now decode the events
1513
1514
1515v_tic()
1516        WAVE V_Events = V_Events
1517        uint64 val,b1,b2,btime
1518
1519       
1520        Variable num,ii
1521        num=numpnts(V_Events)
1522       
1523        Make/O/L/U/N=(num) eventTime                    //64 bit unsigned
1524        Make/O/U/B/N=(num) tube,location                //8 bit unsigned
1525
1526// MultiThread is about 10x faster than the for loop
1527 MultiThread tube = (V_Events[p]) & 0xFF       
1528 MultiThread location = (V_Events[p] >> 8 ) & 0xFF     
1529 MultiThread eventTime = (V_Events[p] >> 16)
1530       
1531//      for(ii=0;ii<num;ii+=1)
1532//              val = V_Events[ii]
1533//             
1534////            b1 = (val >> 56 ) & 0xFF                        // = 255, last two bytes, after shifting
1535////            b2 = (val >> 48 ) & 0xFF       
1536////            btime = val & 0xFFFFFFFFFFFF    // = really big number, last 6 bytes
1537//
1538//              b1 = val & 0xFF
1539//              b2 = (val >> 8) & 0xFF
1540//              btime = (val >> 16)
1541//
1542//
1543//              tube[ii] = b1
1544//              location[ii] = b2
1545//              eventTime[ii] = btime
1546//             
1547//      endfor
1548
1549Printf "File decode time (s) = "
1550v_toc()
1551
1552//      KillWaves/Z timePt,xLoc,yLoc
1553//      Rename tube xLoc
1554//      Rename location yLoc
1555//      Rename eventTime timePt
1556//     
1557//      Redimension/D xLoc,yLoc,timePt
1558       
1559
1560// TODO
1561// add more to the status display of the file load/decode
1562//     
1563        // dispStr will be displayed on the panel
1564        fileStr = ParseFilePath(0, filepathstr, ":", 1, 0)
1565       
1566        sprintf tmpStr, "%s: %d total bytes\r",fileStr,totBytes
1567        dispStr = tmpStr
1568        sprintf tmpStr,"numXYevents = %d\r",numXYevents
1569        dispStr += tmpStr
1570//      sPrintf tmpStr,"\rBad Rollover Events = %d (%4.4g %% of events)",numBad,numBad/numXYevents*100
1571//      dispStr += tmpStr
1572//      sPrintf tmpStr,"\rTotal Events Removed = %d (%4.4g %% of events)",numRemoved,numRemoved/numXYevents*100
1573//      dispStr += tmpStr
1574
1575        SetDataFolder root:
1576       
1577        return(0)
1578       
1579End
1580
1581////////////////
1582////
1583//// This calls the XOP, as an operation to load the events
1584////
1585//// -- it's about 35x faster than the Igor code, so I guess that's OK.
1586////
1587//// conditional compile the whole inner workings in case XOP is not present
1588//Function LoadEvents_XOP()
1589//#if (exists("EventLoadWave")==4)
1590//     
1591////    NVAR time_msw = root:Packages:NIST:VSANS:Event:gEvent_time_msw
1592////    NVAR time_lsw = root:Packages:NIST:VSANS:Event:gEvent_time_lsw
1593//      NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
1594//     
1595//      SVAR filepathstr = root:Packages:NIST:VSANS:Event:gEvent_logfile
1596//      SVAR dispStr = root:Packages:NIST:VSANS:Event:gEventDisplayString
1597//     
1598//      SetDataFolder root:Packages:NIST:VSANS:Event
1599//
1600//
1601//
1602//      Variable fileref
1603//      String buffer
1604//      String fileStr,tmpStr
1605//      Variable dataval,timeval,type,numLines,verbose,verbose3
1606//      Variable xval,yval,rollBit,nRoll,roll_time,bit29,bit28,bit27
1607//      Variable ii,flaggedEvent,rolloverHappened,numBad=0,tmpPP=0,tmpT0=0
1608//      Variable Xmax, yMax
1609//     
1610//      xMax = 127              // number the detector from 0->127
1611//      yMax = 127
1612//     
1613//      numLines = 0
1614//
1615//      //Have to declare local variables for Loadwave so that this compiles without XOP.
1616//      String S_waveNames
1617//      //  and those for the XOP
1618//      Variable V_nXYevents,V_num1,V_num2,V_num3,V_num0,V_totBytes,V_numPP,V_numT0,V_numDL,V_numFF,V_numZero
1619//      Variable V_numBad,V_numRemoved
1620//     
1621//      // what I really need is the number of XY events
1622//      Variable numXYevents,num1,num2,num3,num0,totBytes,numPP,numT0,numDL,numFF,numZero
1623//      Variable numRemoved
1624//      numXYevents = 0
1625//      num0 = 0
1626//      num1 = 0
1627//      num2 = 0
1628//      num3 = 0
1629//      numPP = 0
1630//      numT0 = 0
1631//      numDL = 0
1632//      numFF = 0
1633//      numZero = 0
1634//      numRemoved = 0
1635//
1636//// get the total number of bytes in the file
1637//      Open/R fileref as filepathstr
1638//              FStatus fileref
1639//      Close fileref
1640//
1641//      totBytes = V_logEOF
1642//      Print "total bytes = ", totBytes
1643//     
1644////
1645////    Print "scan only"
1646////    tic()
1647////            EventLoadWave/R/N=EventWave/W filepathstr
1648////    toc()
1649//
1650//////
1651////
1652////  use the XOP operation to load in the data
1653//// -- this does everything - the pre-scan and creating the waves
1654////
1655//// need to zero the waves before loading, just in case
1656////
1657//
1658//      NVAR removeBadEvents = root:Packages:NIST:VSANS:Event:gRemoveBadEvents
1659//
1660//v_tic()
1661//
1662////    Wave/Z wave0=wave0
1663////    Wave/Z wave1=wave1
1664////    Wave/Z wave2=wave2
1665////
1666////    if(WaveExists(wave0))
1667////            MultiThread wave0=0
1668////    endif
1669////    if(WaveExists(wave1))
1670////            MultiThread wave1=0
1671////    endif
1672////    if(WaveExists(wave2))
1673////            MultiThread wave2=0
1674////    endif
1675//
1676//      if(removeBadEvents)
1677//              EventLoadWave/R/N=EventWave filepathstr
1678//      else
1679//              EventLoadWave/N=EventWave  filepathstr
1680//      endif
1681//
1682//
1683//      Print "XOP files loaded = ",S_waveNames
1684//
1685//////          -- copy the waves over to xLoc,yLoc,timePt
1686//      Wave/Z EventWave0=EventWave0
1687//      Wave/Z EventWave1=EventWave1
1688//      Wave/Z EventWave2=EventWave2
1689//     
1690//     
1691//      Duplicate/O EventWave0,xLoc
1692//      KillWaves/Z EventWave0
1693//
1694//      Duplicate/O EventWave1,yLoc
1695//      KillWaves/Z EventWave1
1696//
1697//      Duplicate/O EventWave2,timePt
1698//      KillWaves/Z EventWave2
1699//
1700//// could do this, but rescaled time will neeed to be converted to SP (or DP)
1701//// and Igor loader was written with Make generating SP/DP waves
1702//      // /I/U is unsigned 32-bit integer (for the time)
1703//      // /B/U is unsigned 8-bit integer (max val=255) for the x and y values
1704//     
1705////    Redimension/B/U xLoc,yLoc
1706////    Redimension/I/U timePt
1707//
1708//      // access the variables from the XOP
1709//      numT0 = V_numT0
1710//      numPP = V_numPP
1711//      num0 = V_num0
1712//      num1 = V_num1
1713//      num2 = V_num2
1714//      num3 = V_num3
1715//      numXYevents = V_nXYevents
1716//      numZero = V_numZero
1717//      numBad = V_numBad
1718//      numRemoved = V_numRemoved
1719//     
1720//      Print "(XOP) numT0 = ",numT0   
1721//      Print "num0 = ",num0   
1722//      Print "num1 = ",num1   
1723//      Print "num2 = ",num2   
1724//      Print "num3 = ",num3   
1725//     
1726//
1727//// dispStr will be displayed on the panel
1728//      fileStr = ParseFilePath(0, filepathstr, ":", 1, 0)
1729//     
1730//      sprintf tmpStr, "%s: %d total bytes\r",fileStr,totBytes
1731//      dispStr = tmpStr
1732//      sprintf tmpStr,"numXYevents = %d\r",numXYevents
1733//      dispStr += tmpStr
1734//      sprintf tmpStr,"PP = %d  :  ",numPP
1735//      dispStr += tmpStr
1736//      sprintf tmpStr,"ZeroData = %d\r",numZero
1737//      dispStr += tmpStr
1738//      sprintf tmpStr,"Rollover = %d",num3
1739//      dispStr += tmpStr
1740//
1741//      v_toc()
1742//     
1743//      Print "Events removed (XOP) = ",numRemoved
1744//     
1745//      sPrintf tmpStr,"\rBad Rollover Events = %d (%4.4g %% of events)",numBad,numBad/numXYevents*100
1746//      dispStr += tmpStr
1747//      sPrintf tmpStr,"\rTotal Events Removed = %d (%4.4g %% of events)",numRemoved,numRemoved/numXYevents*100
1748//      dispStr += tmpStr
1749//
1750//
1751//// simply to compile a table of # XY vs # bytes
1752////    Wave/Z nxy = root:numberXY
1753////    Wave/Z nBytes = root:numberBytes
1754////    if(WaveExists(nxy) && WaveExists(nBytes))
1755////            InsertPoints 0, 1, nxy,nBytes
1756////            nxy[0] = numXYevents
1757////            nBytes[0] = totBytes
1758////    endif
1759//
1760//      SetDataFolder root:
1761//
1762//#endif       
1763//      return(0)
1764//     
1765//End
1766
1767//////////////
1768
1769Proc V_BinEventBarGraph()
1770        Variable sc = 1
1771                       
1772        if(root:Packages:NIST:VSANS:Globals:gLaptopMode == 1)
1773                sc = 0.7
1774        endif
1775       
1776        DoWindow/F V_EventBarGraph
1777        if(V_flag == 0)
1778                PauseUpdate; Silent 1           // building window...
1779                String fldrSav0= GetDataFolder(1)
1780                SetDataFolder root:Packages:NIST:VSANS:Event:
1781                Display /W=(110*sc,705*sc,610*sc,1132*sc)/N=V_EventBarGraph /K=1 binCount vs binEndTime
1782                SetDataFolder fldrSav0
1783                ModifyGraph mode=5
1784                ModifyGraph marker=19
1785                ModifyGraph lSize=2
1786                ModifyGraph rgb=(0,0,0)
1787                ModifyGraph msize=2
1788                ModifyGraph hbFill=2
1789                ModifyGraph gaps=0
1790                ModifyGraph usePlusRGB=1
1791                ModifyGraph toMode=0
1792                ModifyGraph useBarStrokeRGB=1
1793                ModifyGraph standoff=0
1794                SetAxis left 0,*
1795                Label bottom "\\Z14Time (seconds)"
1796                Label left "\\Z14Number of Events"
1797        endif
1798End
1799
1800
1801Proc V_ShowBinTable()
1802        Variable sc = 1
1803                       
1804        if(root:Packages:NIST:VSANS:Globals:gLaptopMode == 1)
1805                sc = 0.7
1806        endif
1807
1808        DoWindow/F V_BinEventTable
1809        if(V_flag == 0)
1810                PauseUpdate; Silent 1           // building window...
1811                String fldrSav0= GetDataFolder(1)
1812                SetDataFolder root:Packages:NIST:VSANS:Event:
1813                Edit/W=(498*sc,699*sc,1003*sc,955*sc) /K=1/N=V_BinEventTable binCount,binEndTime,timeWidth
1814                ModifyTable format(Point)=1,sigDigits(binEndTime)=8,width(binEndTime)=100*sc
1815                SetDataFolder fldrSav0
1816        endif
1817EndMacro
1818
1819
1820// only show the first 1500 data points
1821//
1822Proc V_ShowRescaledTimeGraph()
1823        Variable sc = 1
1824                       
1825        if(root:Packages:NIST:VSANS:Globals:gLaptopMode == 1)
1826                sc = 0.7
1827        endif
1828
1829        DoWindow/F V_RescaledTimeGraph
1830        if(V_flag == 0)
1831                PauseUpdate; Silent 1           // building window...
1832                String fldrSav0= GetDataFolder(1)
1833                SetDataFolder root:Packages:NIST:VSANS:Event:
1834                Display /W=(25*sc,44*sc,486*sc,356*sc)/K=1/N=V_RescaledTimeGraph rescaledTime
1835                SetDataFolder fldrSav0
1836                ModifyGraph mode=4
1837                ModifyGraph marker=19
1838                ModifyGraph rgb(rescaledTime)=(0,0,0)
1839                ModifyGraph msize=1
1840//              SetAxis/A=2 left                        //only autoscale the visible data (based on the bottom limits)
1841                SetAxis bottom 0,1500
1842                ErrorBars rescaledTime OFF
1843                       
1844                if(root:Packages:NIST:VSANS:Globals:gLaptopMode == 1)
1845                        Label left "\\Z10Time (seconds)"
1846                        Label bottom "\\Z10Event number"
1847                else
1848                        Label left "\\Z14Time (seconds)"
1849                        Label bottom "\\Z14Event number"
1850                endif
1851                ShowInfo
1852        endif
1853       
1854EndMacro
1855
1856
1857
1858//Proc ExportSlicesAsVAX(firstNum,prefix)
1859//      Variable firstNum=1
1860//      String prefix="SAMPL"
1861//
1862//      SaveSlicesAsVAX(firstNum,prefix[0,4])           //make sure that the prefix is 5 chars
1863//End
1864
1865////////// procedures to be able to export the slices as RAW VAX files.
1866////
1867//// 1- load the raw data file to use the header (it must already be in RAW)
1868//// 1.5- copy the raw data to the temp folder (STO)
1869//// 1.7- ask for the prefix and starting run number (these are passed in)
1870//// 2- copy the slice of data to the temp folder (STO)
1871//// 3- touch up the time/counts in the slice header values in STO
1872//// 4- write out the VAX file
1873//// 5- repeat (2-4) for the number of slices
1874////
1875////
1876//Function SaveSlicesAsVAX(firstNum,prefix)
1877//      Variable firstNum
1878//      String prefix
1879//
1880//      DoAlert 1,"Is the full data file loaded as a RAW data file? If not, load it and start over..."
1881//      if(V_flag == 2)
1882//              return (0)
1883//      endif
1884//     
1885//// copy the contents of RAW to STO so I can work from there
1886//      CopyWorkContents("RAW","STO")
1887//
1888//      // now declare all of the waves, now that they are sure to be there
1889//
1890//      WAVE slicedData=root:Packages:NIST:VSANS:Event:slicedData
1891//      Make/O/D/N=(128,128) curSlice
1892//     
1893//      NVAR nslices = root:Packages:NIST:VSANS:Event:gEvent_nslices
1894//      WAVE binEndTime = root:Packages:NIST:VSANS:Event:binEndTime
1895//
1896//      Wave rw=root:Packages:NIST:STO:realsRead
1897//      Wave iw=root:Packages:NIST:STO:integersRead
1898//      Wave/T tw=root:Packages:NIST:STO:textRead
1899//      Wave data=root:Packages:NIST:STO:data
1900//      Wave linear_data=root:Packages:NIST:STO:linear_data
1901//     
1902//     
1903//      Wave rw_raw=root:Packages:NIST:RAW:realsRead
1904//      Wave iw_raw=root:Packages:NIST:RAW:integersRead
1905//      Wave/T tw_raw=root:Packages:NIST:RAW:textRead
1906//
1907//// for generating the alphanumeric
1908//      String timeStr= secs2date(datetime,-1)
1909//      String monthStr=StringFromList(1, timeStr  ,"/")
1910//      String numStr="",labelStr
1911//
1912//      Variable ii,err,binFraction
1913//     
1914//      for(ii=0;ii<nslices;ii+=1)
1915//
1916//              //get the current slice and put it in the STO folder
1917//              curSlice = slicedData[p][q][ii]
1918//              data = curSlice
1919//              linear_data = curSlice
1920//             
1921//              // touch up the header as needed
1922//              // count time = iw[2]
1923//              // monCt = rw[0]
1924//              // detCt = rw[2]
1925//              //tw[0] must now be the file name
1926//              //
1927//              // count time = fraction of total binning * total count time
1928//              binFraction = (binEndTime[ii+1]-binEndTime[ii])/(binEndTime[nslices]-binEndTime[0])
1929//             
1930//              iw[2] = trunc(binFraction*iw_raw[2])
1931//              rw[0] = trunc(binFraction*rw_raw[0])
1932//              rw[2] = sum(curSlice,-inf,inf)          //total counts in slice
1933//     
1934//              if(firstNum<10)
1935//                      numStr = "00"+num2str(firstNum)
1936//              else
1937//                      if(firstNum<100)
1938//                              numStr = "0"+num2str(firstNum)
1939//                      else
1940//                              numStr = num2str(firstNum)
1941//                      Endif
1942//              Endif   
1943//              tw[0] = prefix+numstr+".SA2_EVE_"+(num2char(str2num(monthStr)+64))+numStr
1944//              labelStr = tw_raw[6]
1945//             
1946//              labelStr = PadString(labelStr,60,0x20)  //60 fortran-style spaces
1947//              tw[6] = labelStr[0,59]
1948//             
1949//              //write out the file - this uses the tw[0] and home path
1950//              Write_VAXRaw_Data("STO","",0)
1951//
1952//              //increment the run number, alpha
1953//              firstNum += 1   
1954//      endfor
1955//
1956//      return(0)
1957//End
1958//
1959
1960
1961
1962
1963/////////////
1964//The histogramming
1965//
1966// 6 AUG 2012
1967//
1968// from Igor Exchange, RGerkin
1969//  http://www.igorexchange.com/node/1373
1970// -- see the related thread on the mailing list
1971//
1972//Function Setup_JointHistogram()
1973//
1974////    tic()
1975//
1976//      make/D /o/n=1000000 data1=gnoise(1), data2=gnoise(1)
1977//      make/D /o/n=(25,25) myHist
1978//      setscale x,-3,3,myHist
1979//      setscale y,-3,3,myHist
1980//      IndexForHistogram(data1,data2,myhist)
1981//      Wave index=SavedIndex
1982//      JointHistogram(data1,data2,myHist,index)
1983//      NewImage myHist
1984//     
1985////    toc()
1986//     
1987//End
1988
1989
1990// this is not used - it now conflicts with the name of a built-in function in Igor 7
1991//
1992Function xJointHistogram(w0,w1,hist,index)
1993        wave w0,w1,hist,index
1994 
1995        variable bins0=dimsize(hist,0)
1996        variable bins1=dimsize(hist,1)
1997        variable n=numpnts(w0)
1998        variable left0=dimoffset(hist,0)
1999        variable left1=dimoffset(hist,1)
2000        variable right0=left0+bins0*dimdelta(hist,0)
2001        variable right1=left1+bins1*dimdelta(hist,1)
2002       
2003        // Compute the histogram and redimension it. 
2004        histogram /b={0,1,bins0*bins1} index,hist
2005        redimension/D /n=(bins0,bins1) hist // Redimension to 2D. 
2006        setscale x,left0,right0,hist // Fix the histogram scaling in the x-dimension. 
2007        setscale y,left1,right1,hist // Fix the histogram scaling in the y-dimension. 
2008End
2009
2010
2011// histogram with a point range
2012//
2013// x- just need to send x2pnt or findLevel, or something similar to define the POINT
2014// values
2015//
2016// x- can also speed this up since the index only needs to be done once, so the
2017// histogram operation can be done separately, as the bins require
2018//
2019//
2020Function V_JointHistogramWithRange(w0,w1,hist,index,pt1,pt2)
2021        wave w0,w1,hist,index
2022        Variable pt1,pt2
2023 
2024        variable bins0=dimsize(hist,0)
2025        variable bins1=dimsize(hist,1)
2026        variable n=numpnts(w0)
2027        variable left0=dimoffset(hist,0)
2028        variable left1=dimoffset(hist,1)
2029        variable right0=left0+bins0*dimdelta(hist,0)
2030        variable right1=left1+bins1*dimdelta(hist,1)
2031
2032        // Compute the histogram and redimension it. 
2033        histogram /b={0,1,bins0*bins1}/R=[pt1,pt2] index,hist
2034        redimension/D /n=(bins0,bins1) hist // Redimension to 2D. 
2035        setscale x,left0,right0,hist // Fix the histogram scaling in the x-dimension. 
2036        setscale y,left1,right1,hist // Fix the histogram scaling in the y-dimension. 
2037End
2038
2039
2040// just does the indexing, creates wave SavedIndex in the current folder for the index
2041//
2042Function V_IndexForHistogram(w0,w1,hist)
2043        wave w0,w1,hist
2044 
2045        variable bins0=dimsize(hist,0)
2046        variable bins1=dimsize(hist,1)
2047        variable n=numpnts(w0)
2048        variable left0=dimoffset(hist,0)
2049        variable left1=dimoffset(hist,1)
2050        variable right0=left0+bins0*dimdelta(hist,0)
2051        variable right1=left1+bins1*dimdelta(hist,1)
2052 
2053        // Scale between 0 and the number of bins to create an index wave. 
2054        if(ThreadProcessorCount<4) // For older machines, matrixop is faster. 
2055                matrixop /free idx=round(bins0*(w0-left0)/(right0-left0))+bins0*round(bins1*(w1-left1)/(right1-left1))
2056        else // For newer machines with many cores, multithreading with make is faster. 
2057                make/free/n=(n) idx
2058                multithread idx=round(bins0*(w0-left0)/(right0-left0))+bins0*round(bins1*(w1-left1)/(right1-left1))
2059        endif
2060 
2061        KillWaves/Z SavedIndex
2062        MoveWave idx,SavedIndex
2063       
2064//      // Compute the histogram and redimension it. 
2065//      histogram /b={0,1,bins0*bins1} idx,hist
2066//      redimension /n=(bins0,bins1) hist // Redimension to 2D. 
2067//      setscale x,left0,right0,hist // Fix the histogram scaling in the x-dimension. 
2068//      setscale y,left1,right1,hist // Fix the histogram scaling in the y-dimension. 
2069End
2070
2071
2072
2073
2074
2075////////////// Post-processing of the event mode data
2076//
2077//
2078// TODO:
2079// -- this is ALL geared towards ordela event mode data and the 6.7s errors, and bad signal
2080//   I don't know if I'll need any of this for the VSANS event data.
2081//
2082//
2083Proc V_ShowEventCorrectionPanel()
2084        DoWindow/F V_EventCorrectionPanel
2085        if(V_flag ==0)
2086                V_EventCorrectionPanel()
2087        EndIf
2088End
2089
2090Proc V_EventCorrectionPanel()
2091        Variable sc = 1
2092                       
2093        if(root:Packages:NIST:VSANS:Globals:gLaptopMode == 1)
2094                sc = 0.7
2095        endif
2096       
2097        PauseUpdate; Silent 1           // building window...
2098        SetDataFolder root:Packages:NIST:VSANS:Event:
2099       
2100        if(exists("rescaledTime") == 1)
2101                Display /W=(35*sc,44*sc,761*sc,533*sc)/K=2 rescaledTime
2102                DoWindow/C V_EventCorrectionPanel
2103                ModifyGraph mode=4
2104                ModifyGraph marker=19
2105                ModifyGraph rgb=(0,0,0)
2106                ModifyGraph msize=1
2107                ErrorBars rescaledTime OFF
2108                       
2109                if(root:Packages:NIST:VSANS:Globals:gLaptopMode == 1)
2110                        Label left "\\Z10Time (seconds)"
2111                        Label bottom "\\Z10Event number"       
2112                else
2113                        Label left "\\Z14Time (seconds)"
2114                        Label bottom "\\Z14Event number"       
2115                endif
2116                SetAxis bottom 0,0.10*numpnts(rescaledTime)             //show 1st 10% of data for speed in displaying
2117               
2118                ControlBar 100
2119                Button button0,pos={sc*18,12*sc},size={sc*70,20*sc},proc=V_EC_AddCursorButtonProc,title="Cursors"
2120                Button button1,pos={sc*153,12*sc},size={sc*80,20*sc},proc=V_EC_AddTimeButtonProc,title="Add time"
2121                Button button2,pos={sc*153,38*sc},size={sc*80,20*sc},proc=V_EC_SubtractTimeButtonProc,title="Subtr time"
2122                Button button3,pos={sc*153,64*sc},size={sc*90,20*sc},proc=V_EC_TrimPointsButtonProc,title="Trim points"
2123                Button button4,pos={sc*(295+150),12*sc},size={sc*90,20*sc},proc=V_EC_SaveWavesButtonProc,title="Save Waves"
2124                Button button5,pos={sc*295,64*sc},size={sc*100,20*sc},proc=V_EC_FindOutlierButton,title="Find Outlier"
2125                Button button6,pos={sc*18,38*sc},size={sc*80,20*sc},proc=V_EC_ShowAllButtonProc,title="All Data"
2126                Button button7,pos={sc*683,12*sc},size={sc*30,20*sc},proc=V_EC_HelpButtonProc,title="?"
2127                Button button8,pos={sc*658,72*sc},size={sc*60,20*sc},proc=V_EC_DoneButtonProc,title="Done"
2128       
2129                Button button9,pos={sc*295,12*sc},size={sc*110,20*sc},proc=V_EC_FindStepButton_down,title="Find Step Down"
2130                Button button10,pos={sc*295,38*sc},size={sc*110,20*sc},proc=V_EC_FindStepButton_up,title="Find Step Up"
2131                Button button11,pos={sc*(295+150),38*sc},size={sc*110,20*sc},proc=V_EC_DoDifferential,title="Differential"
2132               
2133               
2134        else
2135                DoAlert 0, "Please load some event data, then you'll have something to edit."
2136        endif
2137       
2138        SetDataFolder root:
2139       
2140EndMacro
2141
2142Function V_EC_AddCursorButtonProc(ba) : ButtonControl
2143        STRUCT WMButtonAction &ba
2144
2145        switch( ba.eventCode )
2146                case 2: // mouse up
2147                        // click code here
2148                        SetDataFolder root:Packages:NIST:VSANS:Event:
2149                       
2150                        Wave rescaledTime = rescaledTime
2151                        Cursor/P A rescaledTime 0
2152                        Cursor/P B rescaledTime numpnts(rescaledTime)-1
2153                        ShowInfo
2154                        SetDataFolder root:
2155                        break
2156                case -1: // control being killed
2157                        break
2158        endswitch
2159
2160        return 0
2161End
2162
2163// updates the longest time (as does every operation of adjusting the data)
2164//
2165Function V_EC_AddTimeButtonProc(ba) : ButtonControl
2166        STRUCT WMButtonAction &ba
2167
2168        switch( ba.eventCode )
2169                case 2: // mouse up
2170                        // click code here
2171                        SetDataFolder root:Packages:NIST:VSANS:Event:
2172                       
2173                        Wave rescaledTime = rescaledTime
2174                        Wave timePt = timePt
2175                        Variable rollTime,rollTicks,ptA,ptB,lo,hi
2176                       
2177                        rollTicks = 2^26                                // in ticks
2178                        rollTime = 2^26*1e-7            // in seconds
2179                        ptA = pcsr(A)
2180                        ptB = pcsr(B)
2181                        lo=min(ptA,ptB)
2182                        hi=max(ptA,ptB)
2183
2184                        MultiThread timePt[lo,hi] += rollTicks
2185                        MultiThread rescaledTime[lo,hi] += rollTime
2186
2187                        // updates the longest time (as does every operation of adjusting the data)
2188                        NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
2189                        t_longest = waveMax(rescaledTime)
2190                       
2191                        SetDataFolder root:
2192                        break
2193                case -1: // control being killed
2194                        break
2195        endswitch
2196
2197        return 0
2198End
2199
2200Function V_EC_SubtractTimeButtonProc(ba) : ButtonControl
2201        STRUCT WMButtonAction &ba
2202
2203        switch( ba.eventCode )
2204                case 2: // mouse up
2205                        // click code here
2206                        SetDataFolder root:Packages:NIST:VSANS:Event:
2207                       
2208                        Wave rescaledTime = rescaledTime
2209                        Wave timePt = timePt
2210                        Variable rollTime,rollTicks,ptA,ptB,lo,hi
2211                       
2212                        rollTicks = 2^26                                // in ticks
2213                        rollTime = 2^26*1e-7            // in seconds
2214                        ptA = pcsr(A)
2215                        ptB = pcsr(B)
2216                        lo=min(ptA,ptB)
2217                        hi=max(ptA,ptB)
2218                       
2219                        MultiThread timePt[lo,hi] -= rollTicks
2220                        MultiThread rescaledTime[lo,hi] -= rollTime
2221
2222                        // updates the longest time (as does every operation of adjusting the data)
2223                        NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
2224                        t_longest = waveMax(rescaledTime)
2225                       
2226                        SetDataFolder root:
2227                       
2228                        break
2229                case -1: // control being killed
2230                        break
2231        endswitch
2232
2233        return 0
2234End
2235
2236// points removed are inclusive
2237//
2238// put both cursors on the same point to remove just that single point
2239//
2240Function V_EC_TrimPointsButtonProc(ba) : ButtonControl
2241        STRUCT WMButtonAction &ba
2242
2243        switch( ba.eventCode )
2244                case 2: // mouse up
2245                        // click code here
2246                        SetDataFolder root:Packages:NIST:VSANS:Event:
2247                       
2248                        Wave rescaledTime = rescaledTime
2249                        Wave timePt = timePt
2250                        Wave xLoc = xLoc
2251                        Wave yLoc = yLoc
2252                        Variable rollTime,ptA,ptB,numElements,lo,hi
2253                       
2254                        rollTime = 2^26*1e-7            // in seconds
2255                        ptA = pcsr(A)
2256                        ptB = pcsr(B)
2257                        lo=min(ptA,ptB)
2258                        hi=max(ptA,ptB)                 
2259                        numElements = abs(ptA-ptB)+1                    //so points removed are inclusive
2260                        DeletePoints lo, numElements, rescaledTime,timePt,xLoc,yLoc
2261                       
2262                        printf "Points %g to %g have been deleted in rescaledTime, timePt, xLoc, and yLoc\r",ptA,ptB
2263                       
2264                        // updates the longest time (as does every operation of adjusting the data)
2265                        NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
2266                        t_longest = waveMax(rescaledTime)
2267                       
2268                        SetDataFolder root:
2269                       
2270                        break
2271                case -1: // control being killed
2272                        break
2273        endswitch
2274
2275        return 0
2276End
2277
2278// un-sort the data first, then save it
2279Function V_EC_SaveWavesButtonProc(ba) : ButtonControl
2280        STRUCT WMButtonAction &ba
2281
2282        switch( ba.eventCode )
2283                case 2: // mouse up
2284                        // click code here
2285                       
2286//                      Execute "UndoTheSorting()"
2287                       
2288                        SetDataFolder root:Packages:NIST:VSANS:Event:
2289                       
2290                        Wave rescaledTime = rescaledTime
2291                        Wave timePt = timePt
2292                        Wave xLoc = xLoc
2293                        Wave yLoc = yLoc
2294                        Save/T xLoc,yLoc,timePt ,rescaledTime           //will ask for a name
2295                       
2296                        SetDataFolder root:
2297                        break
2298                case -1: // control being killed
2299                        break
2300        endswitch
2301
2302        return 0
2303End
2304
2305//
2306// this duplicates all of the bits that would be done if the "load" button was pressed
2307//
2308Function V_EC_ImportWavesButtonProc(ba) : ButtonControl
2309        STRUCT WMButtonAction &ba
2310
2311        switch( ba.eventCode )
2312                case 2: // mouse up
2313                        // click code here
2314                        SetDataFolder root:Packages:NIST:VSANS:Event:
2315
2316                        NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
2317                        SVAR dispStr = root:Packages:NIST:VSANS:Event:gEventDisplayString
2318                        String tmpStr="",fileStr,filePathStr
2319                       
2320                        // load in the waves, saved as Igor text to preserve the data type
2321                        LoadWave/T/O/P=catPathName
2322                        filePathStr = S_fileName
2323                        if(strlen(S_fileName) == 0)
2324                                //user cancelled
2325                                DoAlert 0,"No file selected, nothing done."
2326                                return(0)
2327                        endif
2328                       
2329                        NVAR mode = root:Packages:NIST:VSANS:Event:gEvent_Mode                          // ==0 for "stream", ==1 for Oscillatory
2330                        // clear out the old sort index, if present, since new data is being loaded
2331                        KillWaves/Z OscSortIndex
2332                        Wave timePt=timePt
2333                        Wave rescaledTime=rescaledTime
2334                       
2335                        t_longest = waveMax(rescaledTime)               //should be the last point
2336                       
2337       
2338                        fileStr = ParseFilePath(0, filepathstr, ":", 1, 0)
2339                        sprintf tmpStr, "%s: a user-modified event file\r",fileStr
2340                        dispStr = tmpStr
2341       
2342                        SetDataFolder root:
2343                        break
2344                case -1: // control being killed
2345                        break
2346        endswitch
2347
2348        return 0
2349End
2350
2351
2352Function V_EC_ShowAllButtonProc(ba) : ButtonControl
2353        STRUCT WMButtonAction &ba
2354
2355        switch( ba.eventCode )
2356                case 2: // mouse up
2357                        // click code here
2358                        SetAxis/A
2359                        break
2360                case -1: // control being killed
2361                        break
2362        endswitch
2363
2364        return 0
2365End
2366
2367Function V_EC_HelpButtonProc(ba) : ButtonControl
2368        STRUCT WMButtonAction &ba
2369
2370        switch( ba.eventCode )
2371                case 2: // mouse up
2372                        // click code here
2373                        DisplayHelpTopic/Z "Event Mode Data[Correcting for things that go wrong]"
2374                        break
2375                case -1: // control being killed
2376                        break
2377        endswitch
2378
2379        return 0
2380End
2381
2382Function V_EC_DoneButtonProc(ba) : ButtonControl
2383        STRUCT WMButtonAction &ba
2384
2385        switch( ba.eventCode )
2386                case 2: // mouse up
2387                        // click code here
2388                        DoWindow/K V_EventCorrectionPanel
2389                        break
2390                case -1: // control being killed
2391                        break
2392        endswitch
2393
2394        return 0
2395End
2396
2397//upDown 5 or -5 looks for spikes +5 or -5 std deviations from mean
2398Function V_PutCursorsAtStep(upDown)
2399        Variable upDown
2400       
2401        SetDataFolder root:Packages:NIST:VSANS:Event:
2402
2403        Wave rescaledTime=rescaledTime
2404        Wave rescaledTime_DIF=rescaledTime_DIF
2405        Variable avg,pt,zoom
2406       
2407        zoom = 200              //points in each direction
2408       
2409        WaveStats/M=1/Q rescaledTime_DIF
2410        avg = V_avg
2411               
2412        FindLevel/P/Q rescaledTime_DIF avg*upDown
2413        if(V_flag==0)
2414                pt = V_levelX
2415                WaveStats/Q/R=[pt-zoom,pt+zoom] rescaledTime            // find the max/min y-vallues within the point range
2416        else
2417                Print "Level not found"
2418                return(0)
2419        endif
2420       
2421        Variable loLeft,hiLeft, loBottom,hiBottom
2422        loLeft = V_min*0.98             //+/- 2%
2423        hiLeft = V_max*1.02
2424       
2425        SetAxis left loLeft,hiLeft
2426        SetAxis bottom pnt2x(rescaledTime,pt-zoom),pnt2x(rescaledTime,pt+zoom)
2427       
2428        Cursor/P A rescaledTime pt+2    //at the point
2429        Cursor/P B rescaledTime numpnts(rescaledTime)-1         //at the end
2430
2431        SetDataFolder root:
2432
2433        return(0)
2434End
2435
2436
2437// find the max (or min) of the rescaled time set
2438// and place both cursors there
2439Function V_fFindOutlier()
2440
2441        SetDataFolder root:Packages:NIST:VSANS:Event:
2442
2443        Wave rescaledTime=rescaledTime
2444        Variable avg,pt,zoom,maxPt,minPt,maxVal,minVal
2445       
2446        zoom = 200              //points in each direction
2447       
2448        WaveStats/M=1/Q rescaledTime
2449        maxPt = V_maxLoc
2450        minPt = V_minLoc
2451        avg = V_avg
2452        maxVal = abs(V_max)
2453        minVal = abs(V_min)
2454
2455        pt = abs(maxVal - avg) > abs(minVal - avg) ? maxPt : minPt
2456       
2457//      Variable loLeft,hiLeft, loBottom,hiBottom
2458//      loLeft = V_min*0.98             //+/- 2%
2459//      hiLeft = V_max*1.02
2460       
2461//      SetAxis left loLeft,hiLeft
2462//      SetAxis bottom pnt2x(rescaledTime,pt-zoom),pnt2x(rescaledTime,pt+zoom)
2463       
2464        Cursor/P A rescaledTime pt              //at the point
2465        Cursor/P B rescaledTime pt              //at the same point
2466
2467        SetDataFolder root:
2468       
2469        return(0)
2470End
2471
2472Function V_EC_FindStepButton_down(ctrlName) : ButtonControl
2473        String ctrlName
2474       
2475//      Variable upDown = -5
2476        NVAR upDown = root:Packages:NIST:VSANS:Event:gStepTolerance
2477       
2478        V_PutCursorsAtStep(-1*upDown)
2479
2480        return(0)
2481end
2482
2483
2484Function V_EC_FindStepButton_up(ctrlName) : ButtonControl
2485        String ctrlName
2486       
2487//      Variable upDown = 5
2488        NVAR upDown = root:Packages:NIST:VSANS:Event:gStepTolerance
2489
2490        V_PutCursorsAtStep(upDown)
2491
2492        return(0)
2493end
2494
2495// if the Trim button section is uncommented, it's "Zap outlier"
2496//
2497Function V_EC_FindOutlierButton(ctrlName) : ButtonControl
2498        String ctrlName
2499       
2500        V_fFindOutlier()
2501//
2502//      STRUCT WMButtonAction ba
2503//      ba.eventCode = 2
2504//
2505//      EC_TrimPointsButtonProc(ba)
2506
2507        return(0)
2508end
2509
2510Function V_EC_DoDifferential(ctrlName) : ButtonControl
2511        String ctrlName
2512       
2513        V_DifferentiatedTime()
2514        DoWindow/F V_EventCorrectionPanel
2515       
2516        //if trace is not on graph, add it
2517        SetDataFolder root:Packages:NIST:VSANS:Event:
2518
2519        String list = WaveList("*_DIF", ";", "WIN:V_EventCorrectionPanel")
2520        if(strlen(list) == 0)
2521                AppendToGraph/R rescaledTime_DIF
2522                ModifyGraph msize=1,rgb(rescaledTime_DIF)=(65535,0,0)
2523                ReorderTraces rescaledTime,{rescaledTime_DIF}           // put the differential behind the event data
2524        endif
2525        SetDataFolder root:
2526        return(0)
2527end
2528
2529//////////////   Custom Bins  /////////////////////
2530//
2531//
2532//
2533// make sure that the bins are defined and the waves exist before
2534// trying to draw the panel
2535//
2536Proc V_Show_CustomBinPanel()
2537        DoWindow/F V_CustomBinPanel
2538        if(V_flag ==0)
2539                V_Init_CustomBins()
2540                V_CustomBinPanel()
2541        EndIf
2542End
2543
2544
2545Function V_Init_CustomBins()
2546
2547        NVAR nSlice = root:Packages:NIST:VSANS:Event:gEvent_nslices
2548        NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
2549
2550        Variable/G root:Packages:NIST:VSANS:Event:gEvent_ForceTmaxBin=1         //==1 to enforce t_longest in user-defined custom bins
2551
2552        SetDataFolder root:Packages:NIST:VSANS:Event:
2553               
2554        Make/O/D/N=(nSlice) timeWidth
2555        Make/O/D/N=(nSlice+1) binEndTime,binCount
2556       
2557        timeWidth = t_longest/nslice
2558        binEndTime = p
2559        binCount = p+1 
2560       
2561        SetDataFolder root:
2562       
2563        return(0)
2564End
2565
2566////////////////       
2567//
2568// Allow custom definitions of the bin widths
2569//
2570// Define by the number of bins, and the time width of each bin
2571//
2572// This shares the number of slices and the maximum time with the main panel
2573//
2574Proc V_CustomBinPanel()
2575        Variable sc = 1
2576                       
2577        if(root:Packages:NIST:VSANS:Globals:gLaptopMode == 1)
2578                sc = 0.7
2579        endif
2580
2581        PauseUpdate; Silent 1           // building window...
2582        NewPanel /W=(130*sc,44*sc,851*sc,455*sc)/K=2 /N=V_CustomBinPanel
2583        DoWindow/C V_CustomBinPanel
2584        ModifyPanel fixedSize=1//,noEdit =1
2585        SetDrawLayer UserBack
2586       
2587        Button button0,pos={sc*654,42*sc}, size={sc*50,20*sc},title="Done",fSize=12
2588        Button button0,proc=V_CB_Done_Proc
2589        Button button1,pos={sc*663,14*sc},size={sc*40,20*sc},proc=V_CB_HelpButtonProc,title="?"
2590        Button button2,pos={sc*216,42*sc},size={sc*80,20*sc},title="Update",proc=V_CB_UpdateWavesButton
2591        SetVariable setvar1,pos={sc*23,13*sc},size={sc*160,20*sc},title="Number of slices",fSize=12
2592        SetVariable setvar1,proc=CB_NumSlicesSetVarProc,value=root:Packages:NIST:VSANS:Event:gEvent_nslices
2593        SetVariable setvar2,pos={sc*24,44*sc},size={sc*160,20*sc},title="Max Time (s)",fSize=10
2594        SetVariable setvar2,value=root:Packages:NIST:VSANS:Event:gEvent_t_longest       
2595
2596        CheckBox chkbox1,pos={sc*216,14*sc},title="Enforce Max Time?"
2597        CheckBox chkbox1,variable = root:Packages:NIST:VSANS:Event:gEvent_ForceTmaxBin
2598        Button button3,pos={sc*500,14*sc},size={sc*90,20*sc},proc=V_CB_SaveBinsButtonProc,title="Save Bins"
2599        Button button4,pos={sc*500,42*sc},size={sc*100,20*sc},proc=V_CB_ImportBinsButtonProc,title="Import Bins"       
2600               
2601        SetDataFolder root:Packages:NIST:VSANS:Event:
2602
2603        Display/W=(291*sc,86*sc,706*sc,395*sc)/HOST=V_CustomBinPanel/N=BarGraph binCount vs binEndTime
2604        ModifyGraph mode=5
2605        ModifyGraph marker=19
2606        ModifyGraph lSize=2
2607        ModifyGraph rgb=(0,0,0)
2608        ModifyGraph msize=2
2609        ModifyGraph hbFill=2
2610        ModifyGraph gaps=0
2611        ModifyGraph usePlusRGB=1
2612        ModifyGraph toMode=1
2613        ModifyGraph useBarStrokeRGB=1
2614        ModifyGraph standoff=0
2615        SetAxis left 0,*
2616        Label bottom "\\Z14Time (seconds)"
2617        Label left "\\Z14Number of Events"
2618        SetActiveSubwindow ##
2619       
2620        // and the table
2621        Edit/W=(13*sc,87*sc,280*sc,394*sc)/HOST=V_CustomBinPanel/N=T0
2622        AppendToTable/W=V_CustomBinPanel#T0 timeWidth,binEndTime
2623        ModifyTable width(Point)=40
2624        SetActiveSubwindow ##
2625       
2626        SetDataFolder root:
2627       
2628EndMacro
2629
2630// save the bins - use Igor Text format
2631//
2632Function V_CB_SaveBinsButtonProc(ba) : ButtonControl
2633        STRUCT WMButtonAction &ba
2634
2635        switch( ba.eventCode )
2636                case 2: // mouse up
2637                        // click code here
2638
2639                        SetDataFolder root:Packages:NIST:VSANS:Event:
2640
2641                        Wave timeWidth = timeWidth
2642                        Wave binEndTime = binEndTime
2643                       
2644                        Save/T timeWidth,binEndTime                     //will ask for a name
2645
2646                        break
2647                case -1: // control being killed
2648                        break
2649        endswitch
2650
2651        SetDataFolder root:
2652       
2653        return 0
2654End
2655
2656// Import the bins - use Igor Text format
2657//
2658// -- be sure that the number of bins is reset
2659// -?- how about the t_longest? - this should be set by the load, not here
2660//
2661// -- loads in timeWidth and binEndTime
2662//
2663Function V_CB_ImportBinsButtonProc(ba) : ButtonControl
2664        STRUCT WMButtonAction &ba
2665
2666        switch( ba.eventCode )
2667                case 2: // mouse up
2668                        // click code here
2669                        NVAR nSlice = root:Packages:NIST:VSANS:Event:gEvent_nslices
2670
2671                        SetDataFolder root:Packages:NIST:VSANS:Event:
2672
2673                        // prompt for the load of data
2674                        LoadWave/T/O
2675                        if(strlen(S_fileName) == 0)
2676                                //user cancelled
2677                                DoAlert 0,"No file selected, nothing done."
2678                                return(0)
2679                        endif
2680
2681                        Wave timeWidth = timeWidth
2682                        nSlice = numpnts(timeWidth)
2683                       
2684                        break
2685                case -1: // control being killed
2686                        break
2687        endswitch
2688
2689        SetDataFolder root:
2690       
2691        return 0
2692End
2693
2694
2695
2696//
2697// can either use the widths as stated -- then the end time may not
2698// match the actual end time of the data set
2699//
2700// -- or --
2701//
2702// enforce the end time of the data set to be the end time of the bins,
2703// then the last bin width must be reset to force the constraint
2704//
2705//
2706Function V_CB_UpdateWavesButton(ba) : ButtonControl
2707        STRUCT WMButtonAction &ba
2708
2709        switch( ba.eventCode )
2710                case 2: // mouse up
2711                        // click code here
2712                        NVAR nSlice = root:Packages:NIST:VSANS:Event:gEvent_nslices
2713                        NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
2714                        NVAR enforceTmax = root:Packages:NIST:VSANS:Event:gEvent_ForceTmaxBin
2715                       
2716                        // update the waves, and recalculate everything for the display
2717                        SetDataFolder root:Packages:NIST:VSANS:Event:
2718
2719                        Wave timeWidth = timeWidth
2720                        Wave binEndTime = binEndTime
2721                        Wave binCount = binCount
2722                       
2723                        // use the widths as entered
2724                        binEndTime[0] = 0
2725                        binEndTime[1,] = binEndTime[p-1] + timeWidth[p-1]
2726                       
2727                        // enforce the longest time as the end bin time
2728                        // note that this changes the last time width
2729                        if(enforceTmax)
2730                                binEndTime[nSlice] = t_longest
2731                                timeWidth[nSlice-1] = t_longest - binEndTime[nSlice-1]
2732                        endif
2733                       
2734                        binCount = p+1
2735                        binCount[nSlice] = 0            // last point is zero, just for display
2736//                      binCount *= sign(timeWidth)             //to alert to negative time bins
2737                       
2738                        // make the timeWidth bold and red if the widths are negative
2739                        WaveStats/Q timeWidth
2740                        if(V_min < 0)
2741                                ModifyTable/W=V_CustomBinPanel#T0 style(timeWidth)=1,rgb(timeWidth)=(65535,0,0)                 
2742                        else
2743                                ModifyTable/W=V_CustomBinPanel#T0 style(timeWidth)=0,rgb(timeWidth)=(0,0,0)                     
2744                        endif
2745                       
2746                        break
2747                case -1: // control being killed
2748                        break
2749        endswitch
2750
2751        SetDataFolder root:
2752       
2753        return 0
2754End
2755
2756Function V_CB_HelpButtonProc(ba) : ButtonControl
2757        STRUCT WMButtonAction &ba
2758
2759        switch( ba.eventCode )
2760                case 2: // mouse up
2761                        // click code here
2762                        DisplayHelpTopic/Z "Event Mode Data[Setting up Custom Bin Widths]"
2763                        break
2764                case -1: // control being killed
2765                        break
2766        endswitch
2767
2768        return 0
2769End
2770
2771Function V_CB_Done_Proc(ba) : ButtonControl
2772        STRUCT WMButtonAction &ba
2773       
2774        String win = ba.win
2775        switch (ba.eventCode)
2776                case 2:
2777                        DoWindow/K V_CustomBinPanel
2778                        break
2779        endswitch
2780        return(0)
2781End
2782
2783
2784Function V_CB_NumSlicesSetVarProc(sva) : SetVariableControl
2785        STRUCT WMSetVariableAction &sva
2786
2787        switch( sva.eventCode )
2788                case 1: // mouse up
2789                case 2: // Enter key
2790                case 3: // Live update
2791                        Variable dval = sva.dval
2792                        String sval = sva.sval
2793                        SetDataFolder root:Packages:NIST:VSANS:Event:
2794
2795                        Wave timeWidth = timeWidth
2796                        Wave binEndTime = binEndTime
2797                       
2798                        Redimension/N=(dval) timeWidth
2799                        Redimension/N=(dval+1) binEndTime,binCount
2800                       
2801                        SetDataFolder root:
2802                       
2803                        break
2804                case -1: // control being killed
2805                        break
2806        endswitch
2807
2808        return 0
2809End
2810
2811
2812///////////////////
2813//
2814// utility to split a large file
2815// 100 MB is the recommended size
2816// events can be clipped here, so be sure to trim the ends of the
2817// resulting files as needed.
2818//
2819// - works like the unix 'split' command
2820//
2821//
2822
2823Proc V_SplitBigFile(splitSize, baseStr)
2824        Variable splitSize = 100
2825        String baseStr="split"
2826        Prompt splitSize,"Target file size, in MB"
2827        Prompt baseStr,"File prefix, number will be appended"
2828       
2829       
2830        V_fSplitBigFile(splitSize, baseStr)
2831       
2832        V_ShowSplitFileTable()
2833End
2834
2835Function/S V_fSplitBigFile(splitSize, baseStr)
2836        Variable splitSize
2837        String baseStr         
2838
2839
2840        String fileName=""              // File name, partial path, full path or "" for dialog.
2841        Variable refNum
2842        String str
2843        SVAR listStr = root:Packages:NIST:VSANS:Event:gSplitFileList
2844       
2845        listStr=""              //initialize output list
2846
2847        Variable readSize=1e6           //1 MB
2848        Make/O/B/U/N=(readSize) aBlob                   //1MB worth
2849        Variable numSplit
2850        Variable num,ii,jj,outRef,frac
2851        String thePath, outStr
2852       
2853        Printf "SplitSize = %u MB\r",splitSize
2854        splitSize = trunc(splitSize) * 1e6              // now in bytes
2855       
2856       
2857        // Open file for read.
2858        Open/R/Z=2/F="????"/P=catPathName refNum as fileName
2859        thePath = ParseFilePath(1, S_fileName, ":", 1, 0)
2860        Print "thePath = ",thePath
2861       
2862        // Store results from Open in a safe place.
2863        Variable err = V_flag
2864        String fullPath = S_fileName
2865
2866        if (err == -1)
2867                Print "cancelled by user."
2868                return ("")
2869        endif
2870
2871        FStatus refNum
2872       
2873        Printf "total # bytes = %u\r",V_logEOF
2874
2875        numSplit=0
2876        if(V_logEOF > splitSize)
2877                numSplit = trunc(V_logEOF/splitSize)
2878        endif
2879
2880        frac = V_logEOF - numSplit*splitSize
2881        Print "numSplit = ",numSplit
2882        Printf "frac = %u\r",frac
2883       
2884        num=0
2885        if(frac > readSize)
2886                num = trunc(frac/readSize)
2887        endif
2888
2889       
2890        frac = frac - num*readSize
2891
2892        Print "num = ",num
2893        Printf "frac = %u\r",frac
2894       
2895//      baseStr = "split"
2896       
2897        for(ii=0;ii<numSplit;ii+=1)
2898                outStr = (thePath+baseStr+num2str(ii))
2899//              Print "outStr = ",outStr
2900                Open outRef as outStr
2901
2902                for(jj=0;jj<(splitSize/readSize);jj+=1)
2903                        FBinRead refNum,aBlob
2904                        FBinWrite outRef,aBlob
2905                endfor
2906
2907                Close outRef
2908//              listStr += outStr+";"
2909                listStr += baseStr+num2str(ii)+";"
2910        endfor
2911
2912        Make/O/B/U/N=(frac) leftover
2913        // ii was already incremented past the loop
2914        outStr = (thePath+baseStr+num2str(ii))
2915        Open outRef as outStr
2916        for(jj=0;jj<num;jj+=1)
2917                FBinRead refNum,aBlob
2918                FBinWrite outRef,aBlob
2919        endfor
2920        FBinRead refNum,leftover
2921        FBinWrite outRef,leftover
2922
2923        Close outRef
2924//      listStr += outStr+";"
2925        listStr += baseStr+num2str(ii)+";"
2926
2927        FSetPos refNum,V_logEOF
2928        Close refNum
2929       
2930        KillWaves/Z aBlob,leftover
2931        return(listStr)
2932End
2933
2934//// allows the list of loaded files to be edited
2935//Function ShowSplitFileTable()
2936//
2937//      SVAR str = root:Packages:NIST:VSANS:Event:gSplitFileList
2938//     
2939//      WAVE/T/Z tw = root:Packages:NIST:VSANS:Event:SplitFileWave
2940//      if(waveExists(tw) != 1)
2941//              Make/O/T/N=1 root:Packages:NIST:VSANS:Event:SplitFileWave
2942//              WAVE/T/Z tw = root:Packages:NIST:VSANS:Event:SplitFileWave
2943//      endif
2944//
2945//      List2TextWave(str,tw)
2946//      Edit tw
2947//
2948//      return(0)
2949//End
2950
2951
2952//// save the sliced data, and accumulate slices
2953//  *** this works with sliced data -- that is data that has been PROCESSED
2954//
2955// need some way of ensuring that the slices match up since I'm blindly adding them together.
2956//
2957// mode = 0             wipe out the old accumulated, copy slicedData to accumulatedData
2958// mode = 1             add current slicedData to accumulatedData
2959// mode = 2             copy accumulatedData to slicedData in preparation of export or display
2960// mode = 3             unused...
2961//
2962//      "Split Large File",SplitBigFile()
2963//      "Accumulate First Slice",AccumulateSlices(0)
2964//      "Add Current Slice",AccumulateSlices(1)
2965//      "Display Accumulated Slices",AccumulateSlices(2)       
2966//
2967Function V_AccumulateSlicesButton(ctrlName) : ButtonControl
2968        String ctrlName
2969       
2970        Variable mode
2971        mode = str2num(ctrlName[strlen(ctrlName)-1])
2972//      Print "mode=",mode
2973        V_AccumulateSlices(mode)
2974       
2975        return(0)
2976End
2977
2978Function V_AccumulateSlices(mode)
2979        Variable mode
2980       
2981        SetDataFolder root:Packages:NIST:VSANS:Event:
2982
2983        switch(mode)   
2984                case 0:
2985                        DoAlert 0,"The current data has been copied to the accumulated set. You are now ready to add more data."
2986                        KillWaves/Z accumulatedData
2987                        Duplicate/O slicedData accumulatedData         
2988                        break
2989                case 1:
2990                        DoAlert 0,"The current data has been added to the accumulated data. You can add more data."
2991                        Wave acc=accumulatedData
2992                        Wave cur=slicedData
2993                        acc += cur
2994                        break
2995                case 2:
2996                        DoAlert 0,"The accumulated data is now the display data and is ready for display or export."
2997                        Duplicate/O accumulatedData slicedData
2998                        // do something to "touch" the display to force it to update
2999                        NVAR gLog = root:Packages:NIST:VSANS:Event:gEvent_logint
3000                        V_LogIntEvent_Proc("",gLog)
3001                        break
3002                default:                       
3003                               
3004        endswitch
3005
3006        SetDataFolder root:
3007        return(0)
3008end
3009
3010
3011////////////////////////////////////////////
3012//
3013// Panel and procedures for decimation
3014//
3015////////////////////////////////////////////
3016
3017//Function E_ShowDecimateButton(ctrlName) : ButtonControl
3018//      String ctrlName
3019//
3020//      DoWindow/F DecimatePanel
3021//      if(V_flag ==0)
3022//              Execute "DecimatePanel()"
3023//      endif
3024//End
3025//
3026//
3027//Proc DecimatePanel() //: Panel
3028//     
3029//      PauseUpdate; Silent 1           // building window...
3030//      NewPanel /W=(1602,44,1961,380)/K=1
3031////    ShowTools/A
3032//      Button button0,pos={sc*29,15*sc},size={sc*100,20*sc},proc=SplitFileButtonProc,title="Split Big File"
3033//      SetVariable setvar0,pos={sc*182,55*sc},size={sc*150,15*sc},title="Decimation factor",fsize=10
3034//      SetVariable setvar0,limits={1,inf,1},value= root:Packages:NIST:VSANS:Event:gDecimation
3035//      Button button1,pos={sc*26,245*sc},size={sc*150,20*sc},proc=LoadDecimateButtonProc,title="Load and Decimate"
3036//      Button button2,pos={sc*25,277*sc},size={sc*150,20*sc},proc=ConcatenateButtonProc,title="Concatenate"
3037//      Button button3,pos={sc*25,305*sc},size={sc*150,20*sc},proc=DisplayConcatenatedButtonProc,title="Display Concatenated"
3038//      Button button4,pos={sc*29,52*sc},size={sc*130,20*sc},proc=Stream_LoadDecim,title="Load From List"
3039//     
3040//      GroupBox group0 title="Manual Controls",size={sc*185,112*sc},pos={sc*14,220}
3041//EndMacro
3042
3043
3044Function V_SplitFileButtonProc(ctrlName) : ButtonControl
3045        String ctrlName
3046
3047        Execute "V_SplitBigFile()"
3048End
3049
3050
3051// show all of the data
3052//
3053Proc V_ShowDecimatedGraph()
3054        Variable sc = 1
3055                       
3056        if(root:Packages:NIST:VSANS:Globals:gLaptopMode == 1)
3057                sc = 0.7
3058        endif
3059
3060        DoWindow/F V_DecimatedGraph
3061        if(V_flag == 0)
3062                PauseUpdate; Silent 1           // building window...
3063                String fldrSav0= GetDataFolder(1)
3064                SetDataFolder root:Packages:NIST:VSANS:Event:
3065                Display /W=(25*sc,44*sc,486*sc,356*sc)/K=1/N=V_DecimatedGraph rescaledTime_dec
3066                SetDataFolder fldrSav0
3067                ModifyGraph mode=4
3068                ModifyGraph marker=19
3069                ModifyGraph rgb(rescaledTime_dec)=(0,0,0)
3070                ModifyGraph msize=1
3071                ErrorBars rescaledTime_dec OFF
3072                Label left "\\Z14Time (seconds)"
3073                Label bottom "\\Z14Event number"
3074                ShowInfo
3075        endif
3076       
3077EndMacro
3078
3079// data has NOT been processed
3080//
3081// so work with x,y,t, and rescaled time
3082// variables -- t_longest
3083Function V_ConcatenateButtonProc(ctrlName) : ButtonControl
3084        String ctrlName
3085       
3086        DoAlert 1,"Is this the first file?"
3087        Variable first = V_flag
3088       
3089        V_fConcatenateButton(first)
3090       
3091        return(0)
3092End
3093
3094Function V_fConcatenateButton(first)
3095        Variable first
3096
3097
3098        SetDataFolder root:Packages:NIST:VSANS:Event:
3099
3100        Wave timePt_dTmp=timePt_dTmp
3101        Wave xLoc_dTmp=xLoc_dTmp
3102        Wave yLoc_dTmp=yLoc_dTmp
3103        Wave rescaledTime_dTmp=rescaledTime_dTmp
3104       
3105        NVAR t_longest_dec = root:Packages:NIST:VSANS:Event:gEvent_t_longest_decimated
3106        NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
3107       
3108       
3109        if(first==1)            //1==yes, 2==no
3110                //then copy the files over, adjusting the time to start from zero
3111                // rescaledTime starts from zero (set by the loader)
3112
3113                timePt_dTmp -= timePt_dTmp[0]                   //subtract the first value
3114               
3115                Duplicate/O timePt_dTmp timePt_dec
3116                Duplicate/O xLoc_dTmp xLoc_dec
3117                Duplicate/O yLoc_dTmp yLoc_dec
3118                Duplicate/O rescaledTime_dTmp rescaledTime_dec
3119               
3120                t_longest_dec = t_longest
3121       
3122        else
3123                // concatenate the files + adjust the time
3124                Wave timePt_dec=timePt_dec
3125                Wave xLoc_dec=xLoc_dec
3126                Wave yLoc_dec=yLoc_dec
3127                Wave rescaledTime_dec=rescaledTime_dec
3128
3129                // adjust the times -- assuming they add
3130                // rescaledTime starts from zero (set by the loader)
3131                //
3132                //
3133                rescaledTime_dTmp += rescaledTime_dec[numpnts(rescaledTime_dec)-1]
3134                rescaledTime_dTmp += abs(rescaledTime_dec[numpnts(rescaledTime_dec)-1] - rescaledTime_dec[numpnts(rescaledTime_dec)-2])
3135               
3136                timePt_dTmp -= timePt_dTmp[0]                   //subtract the first value     
3137               
3138                timePt_dTmp += timePt_dec[numpnts(timePt_dec)-1]                // offset by the last point
3139                timePt_dTmp += abs(timePt_dec[numpnts(timePt_dec)-1] - timePt_dec[numpnts(timePt_dec)-2])               // plus delta so there's not a flat step
3140               
3141                Concatenate/NP/O {timePt_dec,timePt_dTmp}, tmp
3142                Duplicate/O tmp timePt_dec
3143               
3144                Concatenate/NP/O {xLoc_dec,xLoc_dTmp}, tmp
3145                Duplicate/O tmp xLoc_dec
3146               
3147                Concatenate/NP/O {yLoc_dec,yLoc_dTmp}, tmp
3148                Duplicate/O tmp yLoc_dec
3149               
3150                Concatenate/NP/O {rescaledTime_dec,rescaledTime_dTmp}, tmp
3151                Duplicate/O tmp rescaledTime_dec
3152               
3153
3154                KillWaves tmp
3155
3156                t_longest_dec = rescaledTime_dec[numpnts(rescaledTime_dec)-1]
3157
3158        endif
3159       
3160       
3161        SetDataFolder root:
3162       
3163        return(0)
3164
3165End
3166
3167Function V_DisplayConcatenatedButtonProc(ctrlName) : ButtonControl
3168        String ctrlName
3169
3170        //copy the files over to the display set for processing
3171        SetDataFolder root:Packages:NIST:VSANS:Event:
3172
3173        Wave timePt_dec=timePt_dec
3174        Wave xLoc_dec=xLoc_dec
3175        Wave yLoc_dec=yLoc_dec
3176        Wave rescaledTime_dec=rescaledTime_dec
3177               
3178        NVAR t_longest_dec = root:Packages:NIST:VSANS:Event:gEvent_t_longest_decimated
3179        NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
3180       
3181        Duplicate/O timePt_dec timePt
3182        Duplicate/O xLoc_dec xLoc
3183        Duplicate/O yLoc_dec yLoc
3184        Duplicate/O rescaledTime_dec rescaledTime
3185       
3186        t_longest = t_longest_dec       
3187       
3188        SetDataFolder root:
3189       
3190        return(0)
3191
3192End
3193
3194
3195
3196// unused, old testing procedure
3197Function V_LoadDecimateButtonProc(ctrlName) : ButtonControl
3198        String ctrlName
3199
3200        V_LoadEventLog_Button("")
3201       
3202        // now decimate
3203        SetDataFolder root:Packages:NIST:VSANS:Event:
3204
3205        Wave timePt=timePt
3206        Wave xLoc=xLoc
3207        Wave yLoc=yLoc
3208        NVAR t_longest_dec = root:Packages:NIST:VSANS:Event:gEvent_t_longest_decimated
3209
3210        NVAR decimation = root:Packages:NIST:VSANS:Event:gDecimation
3211
3212
3213        Duplicate/O timePt, timePt_dTmp
3214        Duplicate/O xLoc, xLoc_dTmp
3215        Duplicate/O yLoc, yLoc_dTmp
3216        Resample/DOWN=(decimation)/N=1 timePt_dTmp
3217        Resample/DOWN=(decimation)/N=1 xLoc_dTmp
3218        Resample/DOWN=(decimation)/N=1 yLoc_dTmp
3219
3220
3221        Duplicate/O timePt_dTmp rescaledTime_dTmp
3222        rescaledTime_dTmp = 1e-7*(timePt_dTmp - timePt_dTmp[0])         //convert to seconds and start from zero
3223        t_longest_dec = waveMax(rescaledTime_dTmp)              //should be the last point
3224
3225        SetDataFolder root:
3226
3227       
3228End
3229
3230
3231
3232
3233
3234
3235
3236////
3237//// loads a list of files, decimating each chunk as it is read in
3238////
3239//Function Stream_LoadDecim(ctrlName)
3240//      String ctrlName
3241//     
3242//      Variable fileref
3243//
3244//      SVAR filename = root:Packages:NIST:VSANS:Event:gEvent_logfile
3245//      NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
3246//
3247//      SVAR listStr = root:Packages:NIST:VSANS:Event:gSplitFileList
3248//      NVAR t_longest_dec = root:Packages:NIST:VSANS:Event:gEvent_t_longest_decimated
3249//      NVAR decimation = root:Packages:NIST:VSANS:Event:gDecimation
3250//
3251//      String pathStr
3252//      PathInfo catPathName
3253//      pathStr = S_Path
3254//
3255//// if "stream" mode is not checked - abort
3256//      NVAR gEventModeRadioVal= root:Packages:NIST:VSANS:Event:gEvent_mode
3257//      if(gEventModeRadioVal != MODE_STREAM)
3258//              Abort "The mode must be 'Stream' to use this function"
3259//              return(0)
3260//      endif
3261//
3262//// if the list has been edited, turn it into a list
3263//      WAVE/T/Z tw = root:Packages:NIST:VSANS:Event:SplitFileWave
3264//      if(WaveExists(tw))
3265//              listStr = TextWave2SemiList(tw)
3266//      else
3267//              ShowSplitFileTable()
3268//              DoAlert 0,"Enter the file names in the table, then click 'Load From List' again."
3269//              return(0)
3270//      endif
3271//     
3272//
3273//      //loop through everything in the list
3274//      Variable num,ii
3275//      num = ItemsInList(listStr)
3276//     
3277//      for(ii=0;ii<num;ii+=1)
3278//
3279//// (1) load the file, prepending the path             
3280//              filename = pathStr + StringFromList(ii, listStr  ,";")
3281//             
3282//
3283//#if (exists("EventLoadWave")==4)
3284//              LoadEvents_XOP()
3285//#else
3286//              LoadEvents()
3287//#endif       
3288//
3289//              SetDataFolder root:Packages:NIST:VSANS:Event:                   //LoadEvents sets back to root:
3290//
3291//              Wave timePt=timePt
3292//              Wave xLoc=xLoc
3293//              Wave yLoc=yLoc
3294//              CleanupTimes(xLoc,yLoc,timePt)          //remove zeroes
3295//
3296//              Duplicate/O timePt rescaledTime
3297//              rescaledTime = 1e-7*(timePt-timePt[0])          //convert to seconds and start from zero
3298//              t_longest = waveMax(rescaledTime)               //should be the last point
3299//             
3300//// (2) do the decimation, just on timePt. create rescaledTime from the decimated timePt       
3301//             
3302//              Duplicate/O timePt, timePt_dTmp
3303//              Duplicate/O xLoc, xLoc_dTmp
3304//              Duplicate/O yLoc, yLoc_dTmp
3305//              Resample/DOWN=(decimation)/N=1 timePt_dTmp
3306//              Resample/DOWN=(decimation)/N=1 xLoc_dTmp
3307//              Resample/DOWN=(decimation)/N=1 yLoc_dTmp
3308//     
3309//     
3310//              Duplicate/O timePt_dTmp rescaledTime_dTmp
3311//              rescaledTime_dTmp = 1e-7*(timePt_dTmp - timePt_dTmp[0])         //convert to seconds and start from zero
3312//              t_longest_dec = waveMax(rescaledTime_dTmp)              //should be the last point
3313//             
3314//
3315//// (3) concatenate
3316//              fConcatenateButton(ii+1)                //passes 1 for the first time, >1 each other time
3317//     
3318//      endfor
3319//
3320//////          Now that everything is decimated and concatenated, create the rescaled time wave
3321////    SetDataFolder root:Packages:NIST:VSANS:Event:                   //LoadEvents sets back to root:
3322////    Wave timePt_dec = timePt_dec
3323////    Duplicate/O timePt_dec rescaledTime_dec
3324////    rescaledTime_dec = 1e-7*(timePt_dec - timePt_dec[0])            //convert to seconds and start from zero
3325////    t_longest_dec = waveMax(rescaledTime_dec)               //should be the last point
3326//     
3327//      DisplayConcatenatedButtonProc("")
3328//     
3329//      SetDataFolder root:
3330//
3331//      return(0)
3332//End
3333//
3334//Function ShowList_ToLoad(ctrlName)
3335//      String ctrlName
3336//     
3337//      ShowSplitFileTable()
3338//     
3339//      return(0)
3340//End
3341
3342
3343////
3344//// loads a list of files that have been adjusted and saved
3345//// -- does not decimate
3346////
3347//Function Stream_LoadAdjustedList(ctrlName)
3348//      String ctrlName
3349//     
3350//      Variable fileref
3351//
3352//      SVAR filename = root:Packages:NIST:VSANS:Event:gEvent_logfile
3353//      NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
3354//
3355//      SVAR listStr = root:Packages:NIST:VSANS:Event:gSplitFileList
3356//      NVAR t_longest_dec = root:Packages:NIST:VSANS:Event:gEvent_t_longest_decimated
3357////    NVAR decimation = root:Packages:NIST:VSANS:Event:gDecimation
3358//
3359//      String pathStr
3360//      PathInfo catPathName
3361//      pathStr = S_Path
3362//
3363//// if "stream" mode is not checked - abort
3364//      NVAR gEventModeRadioVal= root:Packages:NIST:VSANS:Event:gEvent_mode
3365//      if(gEventModeRadioVal != MODE_STREAM)
3366//              Abort "The mode must be 'Stream' to use this function"
3367//              return(0)
3368//      endif
3369//
3370//// if the list has been edited, turn it into a list
3371//      WAVE/T/Z tw = root:Packages:NIST:VSANS:Event:SplitFileWave
3372//      if(WaveExists(tw))
3373//              listStr = TextWave2SemiList(tw)
3374//      else
3375//              ShowSplitFileTable()
3376//              DoAlert 0,"Enter the file names in the table, then click 'Load From List' again."
3377//              return(0)
3378//      endif
3379//     
3380//
3381//      //loop through everything in the list
3382//      Variable num,ii
3383//      num = ItemsInList(listStr)
3384//     
3385//      for(ii=0;ii<num;ii+=1)
3386//
3387//// (1) load the file, prepending the path             
3388//              filename = pathStr + StringFromList(ii, listStr  ,";")
3389//             
3390//              SetDataFolder root:Packages:NIST:VSANS:Event:
3391//              LoadWave/T/O fileName
3392//
3393//              SetDataFolder root:Packages:NIST:VSANS:Event:                   //LoadEvents sets back to root: ??
3394//
3395//// this is what is loaded -- _dec extension is what is concatenated, and will be copied back later
3396//              Wave timePt=timePt
3397//              Wave xLoc=xLoc
3398//              Wave yLoc=yLoc
3399//              Wave rescaledTime=rescaledTime
3400//
3401////            CleanupTimes(xLoc,yLoc,timePt)          //remove zeroes
3402//
3403////            Duplicate/O timePt rescaledTime
3404////            rescaledTime = 1e-7*(timePt-timePt[0])          //convert to seconds and start from zero
3405////            t_longest = waveMax(rescaledTime)               //should be the last point
3406//             
3407//// (2) No decimation
3408//             
3409//              Duplicate/O timePt, timePt_dTmp
3410//              Duplicate/O xLoc, xLoc_dTmp
3411//              Duplicate/O yLoc, yLoc_dTmp
3412//              Duplicate/O rescaledTime, rescaledTime_dTmp
3413//
3414//
3415//// (3) concatenate
3416//              fConcatenateButton(ii+1)                //passes 1 for the first time, >1 each other time
3417//     
3418//      endfor
3419//     
3420//      DisplayConcatenatedButtonProc("")               // this resets the longest time, too
3421//             
3422//      SetDataFolder root:
3423//
3424//      return(0)
3425//End
3426//
3427///////////////////////////////////////
3428//
3429//// dd-mon-yyyy hh:mm:ss -> Event file name
3430//// the VAX uses 24 hr time for hh
3431////
3432//// scans as string elements since I'm reconstructing a string name
3433//Function/S DateAndTime2HSTName(dateandtime)
3434//      string dateAndTime
3435//     
3436//      String day,yr,hh,mm,ss,time_secs
3437//      Variable mon
3438//      string str,monStr,fileStr
3439//     
3440//      str=dateandtime
3441//      sscanf str,"%2s-%3s-%4s %2s:%2s:%2s",day,monStr,yr,hh,mm,ss
3442//      mon = monStr2num(monStr)
3443//
3444//      fileStr = "Event"+yr+num2str(mon)+day+hh+mm+ss+".hst"
3445//      Print fileStr
3446//
3447//      return(fileStr)
3448//end
3449//
3450//// dd-mon-yyyy hh:mm:ss -> Event file name
3451//// the VAX uses 24 hr time for hh
3452////
3453//// scans as string elements since I'm reconstructing a string name
3454//Function DateAndTime2HSTNumber(dateandtime)
3455//      string dateAndTime
3456//     
3457//      String day,yr,hh,mm,ss,time_secs
3458//      Variable mon,num
3459//      string str,monStr,fileStr
3460//     
3461//      str=dateandtime
3462//      sscanf str,"%2s-%3s-%4s %2s:%2s:%2s",day,monStr,yr,hh,mm,ss
3463//      mon = monStr2num(monStr)
3464//
3465//      fileStr = yr+num2str(mon)+day+hh+mm+ss
3466//      num = str2num(fileStr)
3467//
3468//      return(num)
3469//end
3470//
3471//Function HSTName2Num(str)
3472//      String str
3473//     
3474//      Variable num
3475//      sscanf str,"Event%d.hst",num
3476//      return(num)
3477//end
3478///////////////////////////////
Note: See TracBrowser for help on using the repository browser.