source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/VSANS/V_EventModeProcessing.ipf @ 1209

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

Changes: SANS
Added attenuator calibration tables for 3A on NGB30mSANS (measured sept 2019 by John Barker)

VSANS:
Added utilities (untested) for "Super White Beam" mode

Added more links for the help file - to be added soon.

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

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