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

Last change on this file since 1100 was 1100, checked in by srkline, 5 years ago

Significant restructuring of V_ExecuteProtocol to make the logic of the flow more tractable and adaptable in the future.

Added major change to VSANS event mode reduction panel to allow F and M binned events to be saved to a copy of the correspondng data file. A new data reduction panel for multiple slice reduction is now presented for Event data. This allows reduction of a single slice (all 8 F,M panels, back ignored), or all of the slices.

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