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

Last change on this file since 1130 was 1116, checked in by srkline, 4 years ago

adding pdf documentation of VSANS reduction to the tags as a workaround to webster access being cut off.

File size: 89.6 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 = 1501             // 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="No"
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                        KillWaves/Z rescaledTime
1185                        Duplicate/O timePt rescaledTime
1186                v_toc()
1187                v_tic()
1188                printf "rescale time = "
1189        //              rescaledTime = 1*(timePt-timePt[0])             //convert to nanoseconds and start from zero
1190                        rescaledTime = timeStep_s*(timePt-timePt[0])            //convert to seconds and start from zero
1191                v_toc()
1192                v_tic()
1193                printf "find wave Max = "
1194                        t_longest = waveMax(rescaledTime)               //should be the last point     
1195                v_toc()
1196        endif
1197
1198       
1199        if(mode == MODE_OSCILL)         // oscillatory mode - don't adjust the times, we get periodic t0 to reset t=0
1200                KillWaves/Z rescaledTime
1201                Duplicate/O timePt rescaledTime
1202                rescaledTime *= timeStep_s                      //convert to seconds and that's all
1203                t_longest = waveMax(rescaledTime)               //if oscillatory, won't be the last point, so get it this way
1204       
1205                KillWaves/Z OscSortIndex                        //to make sure that there is no old index hanging around
1206        endif
1207
1208// MODE_TISANE
1209
1210
1211// MODE_TOF
1212        if(mode == MODE_TOF)            // TOF mode - don't adjust the times, we get periodic t0 to reset t=0
1213                KillWaves/Z rescaledTime
1214                Duplicate/O timePt rescaledTime
1215                rescaledTime *= timeStep_s              //convert to seconds and that's all
1216                t_longest = waveMax(rescaledTime)               //if oscillatory, won't be the last point, so get it this way
1217       
1218                KillWaves/Z OscSortIndex                        //to make sure that there is no old index hanging around
1219        endif
1220
1221        SetDataFolder root:
1222
1223Variable t2 = ticks
1224
1225        STRUCT WMButtonAction ba
1226        ba.eventCode = 2
1227        V_ShowEventDataButtonProc(ba)
1228
1229Variable t3 = ticks
1230
1231        Print "load and process (s) = ",(t2-t1)/60.15
1232        Print "Overall including graphs (s) = ",(t3-t1)/60.15
1233        return(0)
1234End
1235
1236
1237
1238
1239//
1240// -- MUCH faster to count the number of lines to remove, then delete (N)
1241// rather then delete them one-by-one in the do-loop
1242//
1243Function V_CleanupTimes(xLoc,yLoc,timePt)
1244        Wave xLoc,yLoc,timePt
1245
1246        // start at the back and remove zeros
1247        Variable num=numpnts(xLoc),ii,numToRemove
1248
1249        numToRemove = 0
1250        ii=num
1251        do
1252                ii -= 1
1253                if(timePt[ii] == 0 && xLoc[ii] == 0 && yLoc[ii] == 0)
1254                        numToRemove += 1
1255                endif
1256        while(timePt[ii-1] == 0 && xLoc[ii-1] == 0 && yLoc[ii-1] == 0)
1257       
1258        if(numToRemove != 0)
1259                DeletePoints ii, numToRemove, xLoc,yLoc,timePt
1260        endif
1261       
1262        return(0)
1263End
1264
1265Function V_LogIntEvent_Proc(ctrlName,checked) : CheckBoxControl
1266        String ctrlName
1267        Variable checked
1268               
1269        SetDataFolder root:Packages:NIST:VSANS:Event
1270       
1271        Wave slicedData = slicedData
1272        Wave logSlicedData = logSlicedData
1273        Wave dispSliceData = dispSliceData
1274       
1275        if(checked)
1276                logslicedData = log(slicedData)
1277                Duplicate/O logslicedData dispsliceData
1278        else
1279                Duplicate/O slicedData dispsliceData
1280        endif
1281
1282        NVAR selectedslice = root:Packages:NIST:VSANS:Event:gEvent_tsdisp
1283
1284        V_sliceSelectEvent_Proc("", selectedslice, "", "")
1285
1286        SetDataFolder root:
1287
1288End
1289
1290
1291// (DONE)
1292// this "fails" for data sets that have 3 or 4 slices, as the ModifyImage command
1293// interprets the data as being RGB - and so does nothing.
1294// need to find a way around this
1295//
1296////  When first plotted, AppendImage/G=1 flag prevents interpretation as RGB so 3, 4 slices display correctly
1297///
1298// I could modify this procedure to use the log = 0|1 keyword for the log Z display
1299// rather than creating a duplicate wave of log(data)
1300//
1301Function V_sliceSelectEvent_Proc(ctrlName, varNum, varStr, varName) : SetVariableControl
1302        String ctrlName
1303        Variable varNum
1304        String varStr
1305        String varName
1306       
1307        NVAR nslices = root:Packages:NIST:VSANS:Event:gEvent_nslices
1308        NVAR selectedslice = root:Packages:NIST:VSANS:Event:gEvent_tsdisp
1309       
1310        if(varNum < 0)
1311                selectedslice = 0
1312                DoUpdate
1313        elseif (varNum > nslices-1)
1314                selectedslice = nslices-1
1315                DoUpdate
1316        else
1317                ModifyImage/W=VSANS_EventModePanel#Event_slicegraph ''#0 plane = varNum
1318        endif
1319
1320End
1321
1322Function V_DifferentiatedTime()
1323
1324        Wave rescaledTime = root:Packages:NIST:VSANS:Event:rescaledTime
1325
1326        SetDataFolder root:Packages:NIST:VSANS:Event:
1327               
1328        Differentiate rescaledTime/D=rescaledTime_DIF
1329//      Display rescaledTime,rescaledTime_DIF
1330        DoWindow/F V_Differentiated_Time
1331        if(V_flag == 0)
1332                Display/N=V_Differentiated_Time/K=1 rescaledTime_DIF
1333                Legend
1334                Modifygraph gaps=0
1335                ModifyGraph zero(left)=1
1336                Label left "\\Z14Delta (dt/event)"
1337                Label bottom "\\Z14Event number"
1338        endif
1339       
1340        SetDataFolder root:
1341       
1342        return(0)
1343End
1344
1345
1346//
1347// for the bit shifts, see the decimal-binary conversion
1348// http://www.binaryconvert.com/convert_unsigned_int.html
1349//
1350//  for 64-bit values:
1351// http://calc.penjee.com
1352//
1353//
1354//
1355//              K0 = 536870912
1356//              Print (K0 & 0x08000000)/134217728       //bit 27 only, shift by 2^27
1357//              Print (K0 & 0x10000000)/268435456               //bit 28 only, shift by 2^28
1358//              Print (K0 & 0x20000000)/536870912               //bit 29 only, shift by 2^29
1359//
1360//
1361//
1362// This function loads the events, and decodes them.
1363// Assigning them to detector panels is a separate function
1364//
1365//
1366//
1367Function V_LoadEvents()
1368       
1369        NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
1370       
1371        SVAR filepathstr = root:Packages:NIST:VSANS:Event:gEvent_logfile
1372        SVAR dispStr = root:Packages:NIST:VSANS:Event:gEventDisplayString
1373       
1374        SetDataFolder root:Packages:NIST:VSANS:Event
1375
1376        Variable refnum
1377        String buffer
1378        String fileStr,tmpStr
1379        Variable verbose
1380        Variable xval,yval
1381        Variable numXYevents,totBytes
1382
1383//  to read a VSANS event file:
1384//
1385// - get the file name
1386//      - read the header (all of it, since I need parts of it) (maybe read as a struct? but I don't know the size!)
1387// - move to EOF and close
1388//
1389// - Use GBLoadWave to read the 64-bit events in
1390
1391
1392/// globals to report the header back for use or status
1393        SVAR gVSANSStr = root:Packages:NIST:VSANS:Event:gVsansStr
1394        NVAR gRevision = root:Packages:NIST:VSANS:Event:gRevision
1395        NVAR gOffset = root:Packages:NIST:VSANS:Event:gOffset           // = 22 bytes if no disabled tubes
1396        NVAR gTime1 = root:Packages:NIST:VSANS:Event:gTime1
1397        NVAR gTime2 = root:Packages:NIST:VSANS:Event:gTime2
1398        NVAR gTime3 = root:Packages:NIST:VSANS:Event:gTime3
1399        NVAR gTime4 = root:Packages:NIST:VSANS:Event:gTime4     // these 4 time pieces are supposed to be 8 bytes total
1400        NVAR gTime5 = root:Packages:NIST:VSANS:Event:gTime5     // these 5 time pieces are supposed to be 10 bytes total
1401        SVAR gDetStr = root:Packages:NIST:VSANS:Event:gDetStr
1402        NVAR gVolt = root:Packages:NIST:VSANS:Event:gVolt
1403        NVAR gResol = root:Packages:NIST:VSANS:Event:gResol             //time resolution in nanoseconds
1404/////
1405
1406        gVSANSStr = PadString(gVSANSStr,5,0x20)         //pad to 5 bytes
1407        gDetStr = PadString(gDetStr,1,0x20)                             //pad to 1 byte
1408
1409        numXYevents = 0
1410
1411
1412        Open/R refnum as filepathstr
1413       
1414v_tic()
1415
1416        FBinRead refnum, gVSANSStr
1417        FBinRead/F=2/U refnum, gRevision
1418        FBinRead/F=2/U refnum, gOffset
1419        FBinRead/F=2/U refnum, gTime1
1420        FBinRead/F=2/U refnum, gTime2
1421        FBinRead/F=2/U refnum, gTime3
1422        FBinRead/F=2/U refnum, gTime4
1423        FBinRead/F=2/U refnum, gTime5
1424        FBinRead refnum, gDetStr
1425        FBinRead/F=2/U refnum, gVolt
1426        FBinRead/F=3/U refnum, gResol
1427
1428        FStatus refnum
1429        FSetPos refnum, V_logEOF
1430       
1431        Close refnum
1432       
1433// number of data bytes
1434        numXYevents = (V_logEOF-gOffset)/8
1435        Print "Number of data values = ",numXYevents
1436       
1437        GBLoadWave/B/T={192,192}/W=1/S=(gOffset) filepathstr
1438       
1439        Duplicate/O $(StringFromList(0,S_waveNames)) V_Events
1440        KillWaves/Z $(StringFromList(0,S_waveNames))
1441
1442Printf "Time to read file (s) = "
1443v_toc()
1444
1445
1446        totBytes = V_logEOF
1447        Print "total bytes = ", totBytes
1448       
1449
1450// V_Events is the uint64 wave that was read in
1451//
1452////// Now decode the events
1453
1454
1455v_tic()
1456        WAVE V_Events = V_Events
1457        uint64 val,b1,b2,btime
1458
1459       
1460        Variable num,ii
1461        num=numpnts(V_Events)
1462       
1463        Make/O/L/U/N=(num) eventTime                    //64 bit unsigned
1464        Make/O/U/B/N=(num) tube,location                //8 bit unsigned
1465
1466// MultiThread is about 10x faster than the for loop
1467 MultiThread tube = (V_Events[p]) & 0xFF       
1468 MultiThread location = (V_Events[p] >> 8 ) & 0xFF     
1469 MultiThread eventTime = (V_Events[p] >> 16)
1470       
1471//      for(ii=0;ii<num;ii+=1)
1472//              val = V_Events[ii]
1473//             
1474////            b1 = (val >> 56 ) & 0xFF                        // = 255, last two bytes, after shifting
1475////            b2 = (val >> 48 ) & 0xFF       
1476////            btime = val & 0xFFFFFFFFFFFF    // = really big number, last 6 bytes
1477//
1478//              b1 = val & 0xFF
1479//              b2 = (val >> 8) & 0xFF
1480//              btime = (val >> 16)
1481//
1482//
1483//              tube[ii] = b1
1484//              location[ii] = b2
1485//              eventTime[ii] = btime
1486//             
1487//      endfor
1488
1489Printf "File decode time (s) = "
1490v_toc()
1491
1492//      KillWaves/Z timePt,xLoc,yLoc
1493//      Rename tube xLoc
1494//      Rename location yLoc
1495//      Rename eventTime timePt
1496//     
1497//      Redimension/D xLoc,yLoc,timePt
1498       
1499
1500// TODO
1501// add more to the status display of the file load/decode
1502//     
1503        // dispStr will be displayed on the panel
1504        fileStr = ParseFilePath(0, filepathstr, ":", 1, 0)
1505       
1506        sprintf tmpStr, "%s: %d total bytes\r",fileStr,totBytes
1507        dispStr = tmpStr
1508        sprintf tmpStr,"numXYevents = %d\r",numXYevents
1509        dispStr += tmpStr
1510//      sPrintf tmpStr,"\rBad Rollover Events = %d (%4.4g %% of events)",numBad,numBad/numXYevents*100
1511//      dispStr += tmpStr
1512//      sPrintf tmpStr,"\rTotal Events Removed = %d (%4.4g %% of events)",numRemoved,numRemoved/numXYevents*100
1513//      dispStr += tmpStr
1514
1515        SetDataFolder root:
1516       
1517        return(0)
1518       
1519End
1520
1521////////////////
1522////
1523//// This calls the XOP, as an operation to load the events
1524////
1525//// -- it's about 35x faster than the Igor code, so I guess that's OK.
1526////
1527//// conditional compile the whole inner workings in case XOP is not present
1528//Function LoadEvents_XOP()
1529//#if (exists("EventLoadWave")==4)
1530//     
1531////    NVAR time_msw = root:Packages:NIST:VSANS:Event:gEvent_time_msw
1532////    NVAR time_lsw = root:Packages:NIST:VSANS:Event:gEvent_time_lsw
1533//      NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
1534//     
1535//      SVAR filepathstr = root:Packages:NIST:VSANS:Event:gEvent_logfile
1536//      SVAR dispStr = root:Packages:NIST:VSANS:Event:gEventDisplayString
1537//     
1538//      SetDataFolder root:Packages:NIST:VSANS:Event
1539//
1540//
1541//
1542//      Variable fileref
1543//      String buffer
1544//      String fileStr,tmpStr
1545//      Variable dataval,timeval,type,numLines,verbose,verbose3
1546//      Variable xval,yval,rollBit,nRoll,roll_time,bit29,bit28,bit27
1547//      Variable ii,flaggedEvent,rolloverHappened,numBad=0,tmpPP=0,tmpT0=0
1548//      Variable Xmax, yMax
1549//     
1550//      xMax = 127              // number the detector from 0->127
1551//      yMax = 127
1552//     
1553//      numLines = 0
1554//
1555//      //Have to declare local variables for Loadwave so that this compiles without XOP.
1556//      String S_waveNames
1557//      //  and those for the XOP
1558//      Variable V_nXYevents,V_num1,V_num2,V_num3,V_num0,V_totBytes,V_numPP,V_numT0,V_numDL,V_numFF,V_numZero
1559//      Variable V_numBad,V_numRemoved
1560//     
1561//      // what I really need is the number of XY events
1562//      Variable numXYevents,num1,num2,num3,num0,totBytes,numPP,numT0,numDL,numFF,numZero
1563//      Variable numRemoved
1564//      numXYevents = 0
1565//      num0 = 0
1566//      num1 = 0
1567//      num2 = 0
1568//      num3 = 0
1569//      numPP = 0
1570//      numT0 = 0
1571//      numDL = 0
1572//      numFF = 0
1573//      numZero = 0
1574//      numRemoved = 0
1575//
1576//// get the total number of bytes in the file
1577//      Open/R fileref as filepathstr
1578//              FStatus fileref
1579//      Close fileref
1580//
1581//      totBytes = V_logEOF
1582//      Print "total bytes = ", totBytes
1583//     
1584////
1585////    Print "scan only"
1586////    tic()
1587////            EventLoadWave/R/N=EventWave/W filepathstr
1588////    toc()
1589//
1590//////
1591////
1592////  use the XOP operation to load in the data
1593//// -- this does everything - the pre-scan and creating the waves
1594////
1595//// need to zero the waves before loading, just in case
1596////
1597//
1598//      NVAR removeBadEvents = root:Packages:NIST:VSANS:Event:gRemoveBadEvents
1599//
1600//v_tic()
1601//
1602////    Wave/Z wave0=wave0
1603////    Wave/Z wave1=wave1
1604////    Wave/Z wave2=wave2
1605////
1606////    if(WaveExists(wave0))
1607////            MultiThread wave0=0
1608////    endif
1609////    if(WaveExists(wave1))
1610////            MultiThread wave1=0
1611////    endif
1612////    if(WaveExists(wave2))
1613////            MultiThread wave2=0
1614////    endif
1615//
1616//      if(removeBadEvents)
1617//              EventLoadWave/R/N=EventWave filepathstr
1618//      else
1619//              EventLoadWave/N=EventWave  filepathstr
1620//      endif
1621//
1622//
1623//      Print "XOP files loaded = ",S_waveNames
1624//
1625//////          -- copy the waves over to xLoc,yLoc,timePt
1626//      Wave/Z EventWave0=EventWave0
1627//      Wave/Z EventWave1=EventWave1
1628//      Wave/Z EventWave2=EventWave2
1629//     
1630//     
1631//      Duplicate/O EventWave0,xLoc
1632//      KillWaves/Z EventWave0
1633//
1634//      Duplicate/O EventWave1,yLoc
1635//      KillWaves/Z EventWave1
1636//
1637//      Duplicate/O EventWave2,timePt
1638//      KillWaves/Z EventWave2
1639//
1640//// could do this, but rescaled time will neeed to be converted to SP (or DP)
1641//// and Igor loader was written with Make generating SP/DP waves
1642//      // /I/U is unsigned 32-bit integer (for the time)
1643//      // /B/U is unsigned 8-bit integer (max val=255) for the x and y values
1644//     
1645////    Redimension/B/U xLoc,yLoc
1646////    Redimension/I/U timePt
1647//
1648//      // access the variables from the XOP
1649//      numT0 = V_numT0
1650//      numPP = V_numPP
1651//      num0 = V_num0
1652//      num1 = V_num1
1653//      num2 = V_num2
1654//      num3 = V_num3
1655//      numXYevents = V_nXYevents
1656//      numZero = V_numZero
1657//      numBad = V_numBad
1658//      numRemoved = V_numRemoved
1659//     
1660//      Print "(XOP) numT0 = ",numT0   
1661//      Print "num0 = ",num0   
1662//      Print "num1 = ",num1   
1663//      Print "num2 = ",num2   
1664//      Print "num3 = ",num3   
1665//     
1666//
1667//// dispStr will be displayed on the panel
1668//      fileStr = ParseFilePath(0, filepathstr, ":", 1, 0)
1669//     
1670//      sprintf tmpStr, "%s: %d total bytes\r",fileStr,totBytes
1671//      dispStr = tmpStr
1672//      sprintf tmpStr,"numXYevents = %d\r",numXYevents
1673//      dispStr += tmpStr
1674//      sprintf tmpStr,"PP = %d  :  ",numPP
1675//      dispStr += tmpStr
1676//      sprintf tmpStr,"ZeroData = %d\r",numZero
1677//      dispStr += tmpStr
1678//      sprintf tmpStr,"Rollover = %d",num3
1679//      dispStr += tmpStr
1680//
1681//      v_toc()
1682//     
1683//      Print "Events removed (XOP) = ",numRemoved
1684//     
1685//      sPrintf tmpStr,"\rBad Rollover Events = %d (%4.4g %% of events)",numBad,numBad/numXYevents*100
1686//      dispStr += tmpStr
1687//      sPrintf tmpStr,"\rTotal Events Removed = %d (%4.4g %% of events)",numRemoved,numRemoved/numXYevents*100
1688//      dispStr += tmpStr
1689//
1690//
1691//// simply to compile a table of # XY vs # bytes
1692////    Wave/Z nxy = root:numberXY
1693////    Wave/Z nBytes = root:numberBytes
1694////    if(WaveExists(nxy) && WaveExists(nBytes))
1695////            InsertPoints 0, 1, nxy,nBytes
1696////            nxy[0] = numXYevents
1697////            nBytes[0] = totBytes
1698////    endif
1699//
1700//      SetDataFolder root:
1701//
1702//#endif       
1703//      return(0)
1704//     
1705//End
1706
1707//////////////
1708
1709Proc V_BinEventBarGraph()
1710       
1711        DoWindow/F V_EventBarGraph
1712        if(V_flag == 0)
1713                PauseUpdate; Silent 1           // building window...
1714                String fldrSav0= GetDataFolder(1)
1715                SetDataFolder root:Packages:NIST:VSANS:Event:
1716                Display /W=(110,705,610,1132)/N=V_EventBarGraph /K=1 binCount vs binEndTime
1717                SetDataFolder fldrSav0
1718                ModifyGraph mode=5
1719                ModifyGraph marker=19
1720                ModifyGraph lSize=2
1721                ModifyGraph rgb=(0,0,0)
1722                ModifyGraph msize=2
1723                ModifyGraph hbFill=2
1724                ModifyGraph gaps=0
1725                ModifyGraph usePlusRGB=1
1726                ModifyGraph toMode=0
1727                ModifyGraph useBarStrokeRGB=1
1728                ModifyGraph standoff=0
1729                SetAxis left 0,*
1730                Label bottom "\\Z14Time (seconds)"
1731                Label left "\\Z14Number of Events"
1732        endif
1733End
1734
1735
1736Proc V_ShowBinTable()
1737
1738        DoWindow/F V_BinEventTable
1739        if(V_flag == 0)
1740                PauseUpdate; Silent 1           // building window...
1741                String fldrSav0= GetDataFolder(1)
1742                SetDataFolder root:Packages:NIST:VSANS:Event:
1743                Edit/W=(498,699,1003,955) /K=1/N=V_BinEventTable binCount,binEndTime,timeWidth
1744                ModifyTable format(Point)=1,sigDigits(binEndTime)=8,width(binEndTime)=100
1745                SetDataFolder fldrSav0
1746        endif
1747EndMacro
1748
1749
1750// only show the first 1500 data points
1751//
1752Proc V_ShowRescaledTimeGraph()
1753
1754        DoWindow/F V_RescaledTimeGraph
1755        if(V_flag == 0)
1756                PauseUpdate; Silent 1           // building window...
1757                String fldrSav0= GetDataFolder(1)
1758                SetDataFolder root:Packages:NIST:VSANS:Event:
1759                Display /W=(25,44,486,356)/K=1/N=V_RescaledTimeGraph rescaledTime
1760                SetDataFolder fldrSav0
1761                ModifyGraph mode=4
1762                ModifyGraph marker=19
1763                ModifyGraph rgb(rescaledTime)=(0,0,0)
1764                ModifyGraph msize=1
1765//              SetAxis/A=2 left                        //only autoscale the visible data (based on the bottom limits)
1766                SetAxis bottom 0,1500
1767                ErrorBars rescaledTime OFF
1768                Label left "\\Z14Time (seconds)"
1769                Label bottom "\\Z14Event number"
1770                ShowInfo
1771        endif
1772       
1773EndMacro
1774
1775
1776
1777//Proc ExportSlicesAsVAX(firstNum,prefix)
1778//      Variable firstNum=1
1779//      String prefix="SAMPL"
1780//
1781//      SaveSlicesAsVAX(firstNum,prefix[0,4])           //make sure that the prefix is 5 chars
1782//End
1783
1784////////// procedures to be able to export the slices as RAW VAX files.
1785////
1786//// 1- load the raw data file to use the header (it must already be in RAW)
1787//// 1.5- copy the raw data to the temp folder (STO)
1788//// 1.7- ask for the prefix and starting run number (these are passed in)
1789//// 2- copy the slice of data to the temp folder (STO)
1790//// 3- touch up the time/counts in the slice header values in STO
1791//// 4- write out the VAX file
1792//// 5- repeat (2-4) for the number of slices
1793////
1794////
1795//Function SaveSlicesAsVAX(firstNum,prefix)
1796//      Variable firstNum
1797//      String prefix
1798//
1799//      DoAlert 1,"Is the full data file loaded as a RAW data file? If not, load it and start over..."
1800//      if(V_flag == 2)
1801//              return (0)
1802//      endif
1803//     
1804//// copy the contents of RAW to STO so I can work from there
1805//      CopyWorkContents("RAW","STO")
1806//
1807//      // now declare all of the waves, now that they are sure to be there
1808//
1809//      WAVE slicedData=root:Packages:NIST:VSANS:Event:slicedData
1810//      Make/O/D/N=(128,128) curSlice
1811//     
1812//      NVAR nslices = root:Packages:NIST:VSANS:Event:gEvent_nslices
1813//      WAVE binEndTime = root:Packages:NIST:VSANS:Event:binEndTime
1814//
1815//      Wave rw=root:Packages:NIST:STO:realsRead
1816//      Wave iw=root:Packages:NIST:STO:integersRead
1817//      Wave/T tw=root:Packages:NIST:STO:textRead
1818//      Wave data=root:Packages:NIST:STO:data
1819//      Wave linear_data=root:Packages:NIST:STO:linear_data
1820//     
1821//     
1822//      Wave rw_raw=root:Packages:NIST:RAW:realsRead
1823//      Wave iw_raw=root:Packages:NIST:RAW:integersRead
1824//      Wave/T tw_raw=root:Packages:NIST:RAW:textRead
1825//
1826//// for generating the alphanumeric
1827//      String timeStr= secs2date(datetime,-1)
1828//      String monthStr=StringFromList(1, timeStr  ,"/")
1829//      String numStr="",labelStr
1830//
1831//      Variable ii,err,binFraction
1832//     
1833//      for(ii=0;ii<nslices;ii+=1)
1834//
1835//              //get the current slice and put it in the STO folder
1836//              curSlice = slicedData[p][q][ii]
1837//              data = curSlice
1838//              linear_data = curSlice
1839//             
1840//              // touch up the header as needed
1841//              // count time = iw[2]
1842//              // monCt = rw[0]
1843//              // detCt = rw[2]
1844//              //tw[0] must now be the file name
1845//              //
1846//              // count time = fraction of total binning * total count time
1847//              binFraction = (binEndTime[ii+1]-binEndTime[ii])/(binEndTime[nslices]-binEndTime[0])
1848//             
1849//              iw[2] = trunc(binFraction*iw_raw[2])
1850//              rw[0] = trunc(binFraction*rw_raw[0])
1851//              rw[2] = sum(curSlice,-inf,inf)          //total counts in slice
1852//     
1853//              if(firstNum<10)
1854//                      numStr = "00"+num2str(firstNum)
1855//              else
1856//                      if(firstNum<100)
1857//                              numStr = "0"+num2str(firstNum)
1858//                      else
1859//                              numStr = num2str(firstNum)
1860//                      Endif
1861//              Endif   
1862//              tw[0] = prefix+numstr+".SA2_EVE_"+(num2char(str2num(monthStr)+64))+numStr
1863//              labelStr = tw_raw[6]
1864//             
1865//              labelStr = PadString(labelStr,60,0x20)  //60 fortran-style spaces
1866//              tw[6] = labelStr[0,59]
1867//             
1868//              //write out the file - this uses the tw[0] and home path
1869//              Write_VAXRaw_Data("STO","",0)
1870//
1871//              //increment the run number, alpha
1872//              firstNum += 1   
1873//      endfor
1874//
1875//      return(0)
1876//End
1877//
1878
1879
1880
1881
1882/////////////
1883//The histogramming
1884//
1885// 6 AUG 2012
1886//
1887// from Igor Exchange, RGerkin
1888//  http://www.igorexchange.com/node/1373
1889// -- see the related thread on the mailing list
1890//
1891//Function Setup_JointHistogram()
1892//
1893////    tic()
1894//
1895//      make/D /o/n=1000000 data1=gnoise(1), data2=gnoise(1)
1896//      make/D /o/n=(25,25) myHist
1897//      setscale x,-3,3,myHist
1898//      setscale y,-3,3,myHist
1899//      IndexForHistogram(data1,data2,myhist)
1900//      Wave index=SavedIndex
1901//      JointHistogram(data1,data2,myHist,index)
1902//      NewImage myHist
1903//     
1904////    toc()
1905//     
1906//End
1907
1908
1909// this is not used - it now conflicts with the name of a built-in function in Igor 7
1910//
1911Function xJointHistogram(w0,w1,hist,index)
1912        wave w0,w1,hist,index
1913 
1914        variable bins0=dimsize(hist,0)
1915        variable bins1=dimsize(hist,1)
1916        variable n=numpnts(w0)
1917        variable left0=dimoffset(hist,0)
1918        variable left1=dimoffset(hist,1)
1919        variable right0=left0+bins0*dimdelta(hist,0)
1920        variable right1=left1+bins1*dimdelta(hist,1)
1921       
1922        // Compute the histogram and redimension it. 
1923        histogram /b={0,1,bins0*bins1} index,hist
1924        redimension/D /n=(bins0,bins1) hist // Redimension to 2D. 
1925        setscale x,left0,right0,hist // Fix the histogram scaling in the x-dimension. 
1926        setscale y,left1,right1,hist // Fix the histogram scaling in the y-dimension. 
1927End
1928
1929
1930// histogram with a point range
1931//
1932// x- just need to send x2pnt or findLevel, or something similar to define the POINT
1933// values
1934//
1935// x- can also speed this up since the index only needs to be done once, so the
1936// histogram operation can be done separately, as the bins require
1937//
1938//
1939Function V_JointHistogramWithRange(w0,w1,hist,index,pt1,pt2)
1940        wave w0,w1,hist,index
1941        Variable pt1,pt2
1942 
1943        variable bins0=dimsize(hist,0)
1944        variable bins1=dimsize(hist,1)
1945        variable n=numpnts(w0)
1946        variable left0=dimoffset(hist,0)
1947        variable left1=dimoffset(hist,1)
1948        variable right0=left0+bins0*dimdelta(hist,0)
1949        variable right1=left1+bins1*dimdelta(hist,1)
1950
1951        // Compute the histogram and redimension it. 
1952        histogram /b={0,1,bins0*bins1}/R=[pt1,pt2] index,hist
1953        redimension/D /n=(bins0,bins1) hist // Redimension to 2D. 
1954        setscale x,left0,right0,hist // Fix the histogram scaling in the x-dimension. 
1955        setscale y,left1,right1,hist // Fix the histogram scaling in the y-dimension. 
1956End
1957
1958
1959// just does the indexing, creates wave SavedIndex in the current folder for the index
1960//
1961Function V_IndexForHistogram(w0,w1,hist)
1962        wave w0,w1,hist
1963 
1964        variable bins0=dimsize(hist,0)
1965        variable bins1=dimsize(hist,1)
1966        variable n=numpnts(w0)
1967        variable left0=dimoffset(hist,0)
1968        variable left1=dimoffset(hist,1)
1969        variable right0=left0+bins0*dimdelta(hist,0)
1970        variable right1=left1+bins1*dimdelta(hist,1)
1971 
1972        // Scale between 0 and the number of bins to create an index wave. 
1973        if(ThreadProcessorCount<4) // For older machines, matrixop is faster. 
1974                matrixop /free idx=round(bins0*(w0-left0)/(right0-left0))+bins0*round(bins1*(w1-left1)/(right1-left1))
1975        else // For newer machines with many cores, multithreading with make is faster. 
1976                make/free/n=(n) idx
1977                multithread idx=round(bins0*(w0-left0)/(right0-left0))+bins0*round(bins1*(w1-left1)/(right1-left1))
1978        endif
1979 
1980        KillWaves/Z SavedIndex
1981        MoveWave idx,SavedIndex
1982       
1983//      // Compute the histogram and redimension it. 
1984//      histogram /b={0,1,bins0*bins1} idx,hist
1985//      redimension /n=(bins0,bins1) hist // Redimension to 2D. 
1986//      setscale x,left0,right0,hist // Fix the histogram scaling in the x-dimension. 
1987//      setscale y,left1,right1,hist // Fix the histogram scaling in the y-dimension. 
1988End
1989
1990
1991
1992
1993
1994////////////// Post-processing of the event mode data
1995//
1996//
1997// TODO:
1998// -- this is ALL geared towards ordela event mode data and the 6.7s errors, and bad signal
1999//   I don't know if I'll need any of this for the VSANS event data.
2000//
2001//
2002Proc V_ShowEventCorrectionPanel()
2003        DoWindow/F V_EventCorrectionPanel
2004        if(V_flag ==0)
2005                V_EventCorrectionPanel()
2006        EndIf
2007End
2008
2009Proc V_EventCorrectionPanel()
2010
2011        PauseUpdate; Silent 1           // building window...
2012        SetDataFolder root:Packages:NIST:VSANS:Event:
2013       
2014        if(exists("rescaledTime") == 1)
2015                Display /W=(35,44,761,533)/K=2 rescaledTime
2016                DoWindow/C V_EventCorrectionPanel
2017                ModifyGraph mode=4
2018                ModifyGraph marker=19
2019                ModifyGraph rgb=(0,0,0)
2020                ModifyGraph msize=1
2021                ErrorBars rescaledTime OFF
2022                Label left "\\Z14Time (seconds)"
2023                Label bottom "\\Z14Event number"       
2024                SetAxis bottom 0,0.10*numpnts(rescaledTime)             //show 1st 10% of data for speed in displaying
2025               
2026                ControlBar 100
2027                Button button0,pos={18,12},size={70,20},proc=V_EC_AddCursorButtonProc,title="Cursors"
2028                Button button1,pos={153,12},size={80,20},proc=V_EC_AddTimeButtonProc,title="Add time"
2029                Button button2,pos={153,38},size={80,20},proc=V_EC_SubtractTimeButtonProc,title="Subtr time"
2030                Button button3,pos={153,64},size={90,20},proc=V_EC_TrimPointsButtonProc,title="Trim points"
2031                Button button4,pos={295+150,12},size={90,20},proc=V_EC_SaveWavesButtonProc,title="Save Waves"
2032                Button button5,pos={295,64},size={100,20},proc=V_EC_FindOutlierButton,title="Find Outlier"
2033                Button button6,pos={18,38},size={80,20},proc=V_EC_ShowAllButtonProc,title="All Data"
2034                Button button7,pos={683,12},size={30,20},proc=V_EC_HelpButtonProc,title="?"
2035                Button button8,pos={658,72},size={60,20},proc=V_EC_DoneButtonProc,title="Done"
2036       
2037                Button button9,pos={295,12},size={110,20},proc=V_EC_FindStepButton_down,title="Find Step Down"
2038                Button button10,pos={295,38},size={110,20},proc=V_EC_FindStepButton_up,title="Find Step Up"
2039                Button button11,pos={295+150,38},size={110,20},proc=V_EC_DoDifferential,title="Differential"
2040               
2041               
2042        else
2043                DoAlert 0, "Please load some event data, then you'll have something to edit."
2044        endif
2045       
2046        SetDataFolder root:
2047       
2048EndMacro
2049
2050Function V_EC_AddCursorButtonProc(ba) : ButtonControl
2051        STRUCT WMButtonAction &ba
2052
2053        switch( ba.eventCode )
2054                case 2: // mouse up
2055                        // click code here
2056                        SetDataFolder root:Packages:NIST:VSANS:Event:
2057                       
2058                        Wave rescaledTime = rescaledTime
2059                        Cursor/P A rescaledTime 0
2060                        Cursor/P B rescaledTime numpnts(rescaledTime)-1
2061                        ShowInfo
2062                        SetDataFolder root:
2063                        break
2064                case -1: // control being killed
2065                        break
2066        endswitch
2067
2068        return 0
2069End
2070
2071// updates the longest time (as does every operation of adjusting the data)
2072//
2073Function V_EC_AddTimeButtonProc(ba) : ButtonControl
2074        STRUCT WMButtonAction &ba
2075
2076        switch( ba.eventCode )
2077                case 2: // mouse up
2078                        // click code here
2079                        SetDataFolder root:Packages:NIST:VSANS:Event:
2080                       
2081                        Wave rescaledTime = rescaledTime
2082                        Wave timePt = timePt
2083                        Variable rollTime,rollTicks,ptA,ptB,lo,hi
2084                       
2085                        rollTicks = 2^26                                // in ticks
2086                        rollTime = 2^26*1e-7            // in seconds
2087                        ptA = pcsr(A)
2088                        ptB = pcsr(B)
2089                        lo=min(ptA,ptB)
2090                        hi=max(ptA,ptB)
2091
2092                        MultiThread timePt[lo,hi] += rollTicks
2093                        MultiThread rescaledTime[lo,hi] += rollTime
2094
2095                        // updates the longest time (as does every operation of adjusting the data)
2096                        NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
2097                        t_longest = waveMax(rescaledTime)
2098                       
2099                        SetDataFolder root:
2100                        break
2101                case -1: // control being killed
2102                        break
2103        endswitch
2104
2105        return 0
2106End
2107
2108Function V_EC_SubtractTimeButtonProc(ba) : ButtonControl
2109        STRUCT WMButtonAction &ba
2110
2111        switch( ba.eventCode )
2112                case 2: // mouse up
2113                        // click code here
2114                        SetDataFolder root:Packages:NIST:VSANS:Event:
2115                       
2116                        Wave rescaledTime = rescaledTime
2117                        Wave timePt = timePt
2118                        Variable rollTime,rollTicks,ptA,ptB,lo,hi
2119                       
2120                        rollTicks = 2^26                                // in ticks
2121                        rollTime = 2^26*1e-7            // in seconds
2122                        ptA = pcsr(A)
2123                        ptB = pcsr(B)
2124                        lo=min(ptA,ptB)
2125                        hi=max(ptA,ptB)
2126                       
2127                        MultiThread timePt[lo,hi] -= rollTicks
2128                        MultiThread rescaledTime[lo,hi] -= rollTime
2129
2130                        // updates the longest time (as does every operation of adjusting the data)
2131                        NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
2132                        t_longest = waveMax(rescaledTime)
2133                       
2134                        SetDataFolder root:
2135                       
2136                        break
2137                case -1: // control being killed
2138                        break
2139        endswitch
2140
2141        return 0
2142End
2143
2144// points removed are inclusive
2145//
2146// put both cursors on the same point to remove just that single point
2147//
2148Function V_EC_TrimPointsButtonProc(ba) : ButtonControl
2149        STRUCT WMButtonAction &ba
2150
2151        switch( ba.eventCode )
2152                case 2: // mouse up
2153                        // click code here
2154                        SetDataFolder root:Packages:NIST:VSANS:Event:
2155                       
2156                        Wave rescaledTime = rescaledTime
2157                        Wave timePt = timePt
2158                        Wave xLoc = xLoc
2159                        Wave yLoc = yLoc
2160                        Variable rollTime,ptA,ptB,numElements,lo,hi
2161                       
2162                        rollTime = 2^26*1e-7            // in seconds
2163                        ptA = pcsr(A)
2164                        ptB = pcsr(B)
2165                        lo=min(ptA,ptB)
2166                        hi=max(ptA,ptB)                 
2167                        numElements = abs(ptA-ptB)+1                    //so points removed are inclusive
2168                        DeletePoints lo, numElements, rescaledTime,timePt,xLoc,yLoc
2169                       
2170                        printf "Points %g to %g have been deleted in rescaledTime, timePt, xLoc, and yLoc\r",ptA,ptB
2171                       
2172                        // updates the longest time (as does every operation of adjusting the data)
2173                        NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
2174                        t_longest = waveMax(rescaledTime)
2175                       
2176                        SetDataFolder root:
2177                       
2178                        break
2179                case -1: // control being killed
2180                        break
2181        endswitch
2182
2183        return 0
2184End
2185
2186// un-sort the data first, then save it
2187Function V_EC_SaveWavesButtonProc(ba) : ButtonControl
2188        STRUCT WMButtonAction &ba
2189
2190        switch( ba.eventCode )
2191                case 2: // mouse up
2192                        // click code here
2193                       
2194//                      Execute "UndoTheSorting()"
2195                       
2196                        SetDataFolder root:Packages:NIST:VSANS:Event:
2197                       
2198                        Wave rescaledTime = rescaledTime
2199                        Wave timePt = timePt
2200                        Wave xLoc = xLoc
2201                        Wave yLoc = yLoc
2202                        Save/T xLoc,yLoc,timePt ,rescaledTime           //will ask for a name
2203                       
2204                        SetDataFolder root:
2205                        break
2206                case -1: // control being killed
2207                        break
2208        endswitch
2209
2210        return 0
2211End
2212
2213//
2214// this duplicates all of the bits that would be done if the "load" button was pressed
2215//
2216Function V_EC_ImportWavesButtonProc(ba) : ButtonControl
2217        STRUCT WMButtonAction &ba
2218
2219        switch( ba.eventCode )
2220                case 2: // mouse up
2221                        // click code here
2222                        SetDataFolder root:Packages:NIST:VSANS:Event:
2223
2224                        NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
2225                        SVAR dispStr = root:Packages:NIST:VSANS:Event:gEventDisplayString
2226                        String tmpStr="",fileStr,filePathStr
2227                       
2228                        // load in the waves, saved as Igor text to preserve the data type
2229                        LoadWave/T/O/P=catPathName
2230                        filePathStr = S_fileName
2231                        if(strlen(S_fileName) == 0)
2232                                //user cancelled
2233                                DoAlert 0,"No file selected, nothing done."
2234                                return(0)
2235                        endif
2236                       
2237                        NVAR mode = root:Packages:NIST:VSANS:Event:gEvent_Mode                          // ==0 for "stream", ==1 for Oscillatory
2238                        // clear out the old sort index, if present, since new data is being loaded
2239                        KillWaves/Z OscSortIndex
2240                        Wave timePt=timePt
2241                        Wave rescaledTime=rescaledTime
2242                       
2243                        t_longest = waveMax(rescaledTime)               //should be the last point
2244                       
2245       
2246                        fileStr = ParseFilePath(0, filepathstr, ":", 1, 0)
2247                        sprintf tmpStr, "%s: a user-modified event file\r",fileStr
2248                        dispStr = tmpStr
2249       
2250                        SetDataFolder root:
2251                        break
2252                case -1: // control being killed
2253                        break
2254        endswitch
2255
2256        return 0
2257End
2258
2259
2260Function V_EC_ShowAllButtonProc(ba) : ButtonControl
2261        STRUCT WMButtonAction &ba
2262
2263        switch( ba.eventCode )
2264                case 2: // mouse up
2265                        // click code here
2266                        SetAxis/A
2267                        break
2268                case -1: // control being killed
2269                        break
2270        endswitch
2271
2272        return 0
2273End
2274
2275Function V_EC_HelpButtonProc(ba) : ButtonControl
2276        STRUCT WMButtonAction &ba
2277
2278        switch( ba.eventCode )
2279                case 2: // mouse up
2280                        // click code here
2281                        DisplayHelpTopic/Z "Event Mode Data[Correcting for things that go wrong]"
2282                        break
2283                case -1: // control being killed
2284                        break
2285        endswitch
2286
2287        return 0
2288End
2289
2290Function V_EC_DoneButtonProc(ba) : ButtonControl
2291        STRUCT WMButtonAction &ba
2292
2293        switch( ba.eventCode )
2294                case 2: // mouse up
2295                        // click code here
2296                        DoWindow/K V_EventCorrectionPanel
2297                        break
2298                case -1: // control being killed
2299                        break
2300        endswitch
2301
2302        return 0
2303End
2304
2305//upDown 5 or -5 looks for spikes +5 or -5 std deviations from mean
2306Function V_PutCursorsAtStep(upDown)
2307        Variable upDown
2308       
2309        SetDataFolder root:Packages:NIST:VSANS:Event:
2310
2311        Wave rescaledTime=rescaledTime
2312        Wave rescaledTime_DIF=rescaledTime_DIF
2313        Variable avg,pt,zoom
2314       
2315        zoom = 200              //points in each direction
2316       
2317        WaveStats/M=1/Q rescaledTime_DIF
2318        avg = V_avg
2319               
2320        FindLevel/P/Q rescaledTime_DIF avg*upDown
2321        if(V_flag==0)
2322                pt = V_levelX
2323                WaveStats/Q/R=[pt-zoom,pt+zoom] rescaledTime            // find the max/min y-vallues within the point range
2324        else
2325                Print "Level not found"
2326                return(0)
2327        endif
2328       
2329        Variable loLeft,hiLeft, loBottom,hiBottom
2330        loLeft = V_min*0.98             //+/- 2%
2331        hiLeft = V_max*1.02
2332       
2333        SetAxis left loLeft,hiLeft
2334        SetAxis bottom pnt2x(rescaledTime,pt-zoom),pnt2x(rescaledTime,pt+zoom)
2335       
2336        Cursor/P A rescaledTime pt+2    //at the point
2337        Cursor/P B rescaledTime numpnts(rescaledTime)-1         //at the end
2338
2339        SetDataFolder root:
2340
2341        return(0)
2342End
2343
2344
2345// find the max (or min) of the rescaled time set
2346// and place both cursors there
2347Function V_fFindOutlier()
2348
2349        SetDataFolder root:Packages:NIST:VSANS:Event:
2350
2351        Wave rescaledTime=rescaledTime
2352        Variable avg,pt,zoom,maxPt,minPt,maxVal,minVal
2353       
2354        zoom = 200              //points in each direction
2355       
2356        WaveStats/M=1/Q rescaledTime
2357        maxPt = V_maxLoc
2358        minPt = V_minLoc
2359        avg = V_avg
2360        maxVal = abs(V_max)
2361        minVal = abs(V_min)
2362
2363        pt = abs(maxVal - avg) > abs(minVal - avg) ? maxPt : minPt
2364       
2365//      Variable loLeft,hiLeft, loBottom,hiBottom
2366//      loLeft = V_min*0.98             //+/- 2%
2367//      hiLeft = V_max*1.02
2368       
2369//      SetAxis left loLeft,hiLeft
2370//      SetAxis bottom pnt2x(rescaledTime,pt-zoom),pnt2x(rescaledTime,pt+zoom)
2371       
2372        Cursor/P A rescaledTime pt              //at the point
2373        Cursor/P B rescaledTime pt              //at the same point
2374
2375        SetDataFolder root:
2376       
2377        return(0)
2378End
2379
2380Function V_EC_FindStepButton_down(ctrlName) : ButtonControl
2381        String ctrlName
2382       
2383//      Variable upDown = -5
2384        NVAR upDown = root:Packages:NIST:VSANS:Event:gStepTolerance
2385       
2386        V_PutCursorsAtStep(-1*upDown)
2387
2388        return(0)
2389end
2390
2391
2392Function V_EC_FindStepButton_up(ctrlName) : ButtonControl
2393        String ctrlName
2394       
2395//      Variable upDown = 5
2396        NVAR upDown = root:Packages:NIST:VSANS:Event:gStepTolerance
2397
2398        V_PutCursorsAtStep(upDown)
2399
2400        return(0)
2401end
2402
2403// if the Trim button section is uncommented, it's "Zap outlier"
2404//
2405Function V_EC_FindOutlierButton(ctrlName) : ButtonControl
2406        String ctrlName
2407       
2408        V_fFindOutlier()
2409//
2410//      STRUCT WMButtonAction ba
2411//      ba.eventCode = 2
2412//
2413//      EC_TrimPointsButtonProc(ba)
2414
2415        return(0)
2416end
2417
2418Function V_EC_DoDifferential(ctrlName) : ButtonControl
2419        String ctrlName
2420       
2421        V_DifferentiatedTime()
2422        DoWindow/F V_EventCorrectionPanel
2423       
2424        //if trace is not on graph, add it
2425        SetDataFolder root:Packages:NIST:VSANS:Event:
2426
2427        String list = WaveList("*_DIF", ";", "WIN:V_EventCorrectionPanel")
2428        if(strlen(list) == 0)
2429                AppendToGraph/R rescaledTime_DIF
2430                ModifyGraph msize=1,rgb(rescaledTime_DIF)=(65535,0,0)
2431                ReorderTraces rescaledTime,{rescaledTime_DIF}           // put the differential behind the event data
2432        endif
2433        SetDataFolder root:
2434        return(0)
2435end
2436
2437//////////////   Custom Bins  /////////////////////
2438//
2439//
2440//
2441// make sure that the bins are defined and the waves exist before
2442// trying to draw the panel
2443//
2444Proc V_Show_CustomBinPanel()
2445        DoWindow/F V_CustomBinPanel
2446        if(V_flag ==0)
2447                V_Init_CustomBins()
2448                V_CustomBinPanel()
2449        EndIf
2450End
2451
2452
2453Function V_Init_CustomBins()
2454
2455        NVAR nSlice = root:Packages:NIST:VSANS:Event:gEvent_nslices
2456        NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
2457
2458        Variable/G root:Packages:NIST:VSANS:Event:gEvent_ForceTmaxBin=1         //==1 to enforce t_longest in user-defined custom bins
2459
2460        SetDataFolder root:Packages:NIST:VSANS:Event:
2461               
2462        Make/O/D/N=(nSlice) timeWidth
2463        Make/O/D/N=(nSlice+1) binEndTime,binCount
2464       
2465        timeWidth = t_longest/nslice
2466        binEndTime = p
2467        binCount = p+1 
2468       
2469        SetDataFolder root:
2470       
2471        return(0)
2472End
2473
2474////////////////       
2475//
2476// Allow custom definitions of the bin widths
2477//
2478// Define by the number of bins, and the time width of each bin
2479//
2480// This shares the number of slices and the maximum time with the main panel
2481//
2482Proc V_CustomBinPanel()
2483        PauseUpdate; Silent 1           // building window...
2484        NewPanel /W=(130,44,851,455)/K=2 /N=V_CustomBinPanel
2485        DoWindow/C V_CustomBinPanel
2486        ModifyPanel fixedSize=1//,noEdit =1
2487        SetDrawLayer UserBack
2488       
2489        Button button0,pos={654,42}, size={50,20},title="Done",fSize=12
2490        Button button0,proc=V_CB_Done_Proc
2491        Button button1,pos={663,14},size={40,20},proc=V_CB_HelpButtonProc,title="?"
2492        Button button2,pos={216,42},size={80,20},title="Update",proc=V_CB_UpdateWavesButton     
2493        SetVariable setvar1,pos={23,13},size={160,20},title="Number of slices",fSize=12
2494        SetVariable setvar1,proc=CB_NumSlicesSetVarProc,value=root:Packages:NIST:VSANS:Event:gEvent_nslices
2495        SetVariable setvar2,pos={24,44},size={160,20},title="Max Time (s)",fSize=10
2496        SetVariable setvar2,value=root:Packages:NIST:VSANS:Event:gEvent_t_longest       
2497
2498        CheckBox chkbox1,pos={216,14},title="Enforce Max Time?"
2499        CheckBox chkbox1,variable = root:Packages:NIST:VSANS:Event:gEvent_ForceTmaxBin
2500        Button button3,pos={500,14},size={90,20},proc=V_CB_SaveBinsButtonProc,title="Save Bins"
2501        Button button4,pos={500,42},size={100,20},proc=V_CB_ImportBinsButtonProc,title="Import Bins"   
2502               
2503        SetDataFolder root:Packages:NIST:VSANS:Event:
2504
2505        Display/W=(291,86,706,395)/HOST=V_CustomBinPanel/N=BarGraph binCount vs binEndTime
2506        ModifyGraph mode=5
2507        ModifyGraph marker=19
2508        ModifyGraph lSize=2
2509        ModifyGraph rgb=(0,0,0)
2510        ModifyGraph msize=2
2511        ModifyGraph hbFill=2
2512        ModifyGraph gaps=0
2513        ModifyGraph usePlusRGB=1
2514        ModifyGraph toMode=1
2515        ModifyGraph useBarStrokeRGB=1
2516        ModifyGraph standoff=0
2517        SetAxis left 0,*
2518        Label bottom "\\Z14Time (seconds)"
2519        Label left "\\Z14Number of Events"
2520        SetActiveSubwindow ##
2521       
2522        // and the table
2523        Edit/W=(13,87,280,394)/HOST=V_CustomBinPanel/N=T0
2524        AppendToTable/W=V_CustomBinPanel#T0 timeWidth,binEndTime
2525        ModifyTable width(Point)=40
2526        SetActiveSubwindow ##
2527       
2528        SetDataFolder root:
2529       
2530EndMacro
2531
2532// save the bins - use Igor Text format
2533//
2534Function V_CB_SaveBinsButtonProc(ba) : ButtonControl
2535        STRUCT WMButtonAction &ba
2536
2537        switch( ba.eventCode )
2538                case 2: // mouse up
2539                        // click code here
2540
2541                        SetDataFolder root:Packages:NIST:VSANS:Event:
2542
2543                        Wave timeWidth = timeWidth
2544                        Wave binEndTime = binEndTime
2545                       
2546                        Save/T timeWidth,binEndTime                     //will ask for a name
2547
2548                        break
2549                case -1: // control being killed
2550                        break
2551        endswitch
2552
2553        SetDataFolder root:
2554       
2555        return 0
2556End
2557
2558// Import the bins - use Igor Text format
2559//
2560// -- be sure that the number of bins is reset
2561// -?- how about the t_longest? - this should be set by the load, not here
2562//
2563// -- loads in timeWidth and binEndTime
2564//
2565Function V_CB_ImportBinsButtonProc(ba) : ButtonControl
2566        STRUCT WMButtonAction &ba
2567
2568        switch( ba.eventCode )
2569                case 2: // mouse up
2570                        // click code here
2571                        NVAR nSlice = root:Packages:NIST:VSANS:Event:gEvent_nslices
2572
2573                        SetDataFolder root:Packages:NIST:VSANS:Event:
2574
2575                        // prompt for the load of data
2576                        LoadWave/T/O
2577                        if(strlen(S_fileName) == 0)
2578                                //user cancelled
2579                                DoAlert 0,"No file selected, nothing done."
2580                                return(0)
2581                        endif
2582
2583                        Wave timeWidth = timeWidth
2584                        nSlice = numpnts(timeWidth)
2585                       
2586                        break
2587                case -1: // control being killed
2588                        break
2589        endswitch
2590
2591        SetDataFolder root:
2592       
2593        return 0
2594End
2595
2596
2597
2598//
2599// can either use the widths as stated -- then the end time may not
2600// match the actual end time of the data set
2601//
2602// -- or --
2603//
2604// enforce the end time of the data set to be the end time of the bins,
2605// then the last bin width must be reset to force the constraint
2606//
2607//
2608Function V_CB_UpdateWavesButton(ba) : ButtonControl
2609        STRUCT WMButtonAction &ba
2610
2611        switch( ba.eventCode )
2612                case 2: // mouse up
2613                        // click code here
2614                        NVAR nSlice = root:Packages:NIST:VSANS:Event:gEvent_nslices
2615                        NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
2616                        NVAR enforceTmax = root:Packages:NIST:VSANS:Event:gEvent_ForceTmaxBin
2617                       
2618                        // update the waves, and recalculate everything for the display
2619                        SetDataFolder root:Packages:NIST:VSANS:Event:
2620
2621                        Wave timeWidth = timeWidth
2622                        Wave binEndTime = binEndTime
2623                        Wave binCount = binCount
2624                       
2625                        // use the widths as entered
2626                        binEndTime[0] = 0
2627                        binEndTime[1,] = binEndTime[p-1] + timeWidth[p-1]
2628                       
2629                        // enforce the longest time as the end bin time
2630                        // note that this changes the last time width
2631                        if(enforceTmax)
2632                                binEndTime[nSlice] = t_longest
2633                                timeWidth[nSlice-1] = t_longest - binEndTime[nSlice-1]
2634                        endif
2635                       
2636                        binCount = p+1
2637                        binCount[nSlice] = 0            // last point is zero, just for display
2638//                      binCount *= sign(timeWidth)             //to alert to negative time bins
2639                       
2640                        // make the timeWidth bold and red if the widths are negative
2641                        WaveStats/Q timeWidth
2642                        if(V_min < 0)
2643                                ModifyTable/W=V_CustomBinPanel#T0 style(timeWidth)=1,rgb(timeWidth)=(65535,0,0)                 
2644                        else
2645                                ModifyTable/W=V_CustomBinPanel#T0 style(timeWidth)=0,rgb(timeWidth)=(0,0,0)                     
2646                        endif
2647                       
2648                        break
2649                case -1: // control being killed
2650                        break
2651        endswitch
2652
2653        SetDataFolder root:
2654       
2655        return 0
2656End
2657
2658Function V_CB_HelpButtonProc(ba) : ButtonControl
2659        STRUCT WMButtonAction &ba
2660
2661        switch( ba.eventCode )
2662                case 2: // mouse up
2663                        // click code here
2664                        DisplayHelpTopic/Z "Event Mode Data[Setting up Custom Bin Widths]"
2665                        break
2666                case -1: // control being killed
2667                        break
2668        endswitch
2669
2670        return 0
2671End
2672
2673Function V_CB_Done_Proc(ba) : ButtonControl
2674        STRUCT WMButtonAction &ba
2675       
2676        String win = ba.win
2677        switch (ba.eventCode)
2678                case 2:
2679                        DoWindow/K V_CustomBinPanel
2680                        break
2681        endswitch
2682        return(0)
2683End
2684
2685
2686Function V_CB_NumSlicesSetVarProc(sva) : SetVariableControl
2687        STRUCT WMSetVariableAction &sva
2688
2689        switch( sva.eventCode )
2690                case 1: // mouse up
2691                case 2: // Enter key
2692                case 3: // Live update
2693                        Variable dval = sva.dval
2694                        String sval = sva.sval
2695                        SetDataFolder root:Packages:NIST:VSANS:Event:
2696
2697                        Wave timeWidth = timeWidth
2698                        Wave binEndTime = binEndTime
2699                       
2700                        Redimension/N=(dval) timeWidth
2701                        Redimension/N=(dval+1) binEndTime,binCount
2702                       
2703                        SetDataFolder root:
2704                       
2705                        break
2706                case -1: // control being killed
2707                        break
2708        endswitch
2709
2710        return 0
2711End
2712
2713
2714///////////////////
2715//
2716// utility to split a large file
2717// 100 MB is the recommended size
2718// events can be clipped here, so be sure to trim the ends of the
2719// resulting files as needed.
2720//
2721// - works like the unix 'split' command
2722//
2723//
2724
2725Proc V_SplitBigFile(splitSize, baseStr)
2726        Variable splitSize = 100
2727        String baseStr="split"
2728        Prompt splitSize,"Target file size, in MB"
2729        Prompt baseStr,"File prefix, number will be appended"
2730       
2731       
2732        V_fSplitBigFile(splitSize, baseStr)
2733       
2734        V_ShowSplitFileTable()
2735End
2736
2737Function/S V_fSplitBigFile(splitSize, baseStr)
2738        Variable splitSize
2739        String baseStr         
2740
2741
2742        String fileName=""              // File name, partial path, full path or "" for dialog.
2743        Variable refNum
2744        String str
2745        SVAR listStr = root:Packages:NIST:VSANS:Event:gSplitFileList
2746       
2747        listStr=""              //initialize output list
2748
2749        Variable readSize=1e6           //1 MB
2750        Make/O/B/U/N=(readSize) aBlob                   //1MB worth
2751        Variable numSplit
2752        Variable num,ii,jj,outRef,frac
2753        String thePath, outStr
2754       
2755        Printf "SplitSize = %u MB\r",splitSize
2756        splitSize = trunc(splitSize) * 1e6              // now in bytes
2757       
2758       
2759        // Open file for read.
2760        Open/R/Z=2/F="????"/P=catPathName refNum as fileName
2761        thePath = ParseFilePath(1, S_fileName, ":", 1, 0)
2762        Print "thePath = ",thePath
2763       
2764        // Store results from Open in a safe place.
2765        Variable err = V_flag
2766        String fullPath = S_fileName
2767
2768        if (err == -1)
2769                Print "cancelled by user."
2770                return ("")
2771        endif
2772
2773        FStatus refNum
2774       
2775        Printf "total # bytes = %u\r",V_logEOF
2776
2777        numSplit=0
2778        if(V_logEOF > splitSize)
2779                numSplit = trunc(V_logEOF/splitSize)
2780        endif
2781
2782        frac = V_logEOF - numSplit*splitSize
2783        Print "numSplit = ",numSplit
2784        Printf "frac = %u\r",frac
2785       
2786        num=0
2787        if(frac > readSize)
2788                num = trunc(frac/readSize)
2789        endif
2790
2791       
2792        frac = frac - num*readSize
2793
2794        Print "num = ",num
2795        Printf "frac = %u\r",frac
2796       
2797//      baseStr = "split"
2798       
2799        for(ii=0;ii<numSplit;ii+=1)
2800                outStr = (thePath+baseStr+num2str(ii))
2801//              Print "outStr = ",outStr
2802                Open outRef as outStr
2803
2804                for(jj=0;jj<(splitSize/readSize);jj+=1)
2805                        FBinRead refNum,aBlob
2806                        FBinWrite outRef,aBlob
2807                endfor
2808
2809                Close outRef
2810//              listStr += outStr+";"
2811                listStr += baseStr+num2str(ii)+";"
2812        endfor
2813
2814        Make/O/B/U/N=(frac) leftover
2815        // ii was already incremented past the loop
2816        outStr = (thePath+baseStr+num2str(ii))
2817        Open outRef as outStr
2818        for(jj=0;jj<num;jj+=1)
2819                FBinRead refNum,aBlob
2820                FBinWrite outRef,aBlob
2821        endfor
2822        FBinRead refNum,leftover
2823        FBinWrite outRef,leftover
2824
2825        Close outRef
2826//      listStr += outStr+";"
2827        listStr += baseStr+num2str(ii)+";"
2828
2829        FSetPos refNum,V_logEOF
2830        Close refNum
2831       
2832        KillWaves/Z aBlob,leftover
2833        return(listStr)
2834End
2835
2836//// allows the list of loaded files to be edited
2837//Function ShowSplitFileTable()
2838//
2839//      SVAR str = root:Packages:NIST:VSANS:Event:gSplitFileList
2840//     
2841//      WAVE/T/Z tw = root:Packages:NIST:VSANS:Event:SplitFileWave
2842//      if(waveExists(tw) != 1)
2843//              Make/O/T/N=1 root:Packages:NIST:VSANS:Event:SplitFileWave
2844//              WAVE/T/Z tw = root:Packages:NIST:VSANS:Event:SplitFileWave
2845//      endif
2846//
2847//      List2TextWave(str,tw)
2848//      Edit tw
2849//
2850//      return(0)
2851//End
2852
2853
2854//// save the sliced data, and accumulate slices
2855//  *** this works with sliced data -- that is data that has been PROCESSED
2856//
2857// need some way of ensuring that the slices match up since I'm blindly adding them together.
2858//
2859// mode = 0             wipe out the old accumulated, copy slicedData to accumulatedData
2860// mode = 1             add current slicedData to accumulatedData
2861// mode = 2             copy accumulatedData to slicedData in preparation of export or display
2862// mode = 3             unused...
2863//
2864//      "Split Large File",SplitBigFile()
2865//      "Accumulate First Slice",AccumulateSlices(0)
2866//      "Add Current Slice",AccumulateSlices(1)
2867//      "Display Accumulated Slices",AccumulateSlices(2)       
2868//
2869Function V_AccumulateSlicesButton(ctrlName) : ButtonControl
2870        String ctrlName
2871       
2872        Variable mode
2873        mode = str2num(ctrlName[strlen(ctrlName)-1])
2874//      Print "mode=",mode
2875        V_AccumulateSlices(mode)
2876       
2877        return(0)
2878End
2879
2880Function V_AccumulateSlices(mode)
2881        Variable mode
2882       
2883        SetDataFolder root:Packages:NIST:VSANS:Event:
2884
2885        switch(mode)   
2886                case 0:
2887                        DoAlert 0,"The current data has been copied to the accumulated set. You are now ready to add more data."
2888                        KillWaves/Z accumulatedData
2889                        Duplicate/O slicedData accumulatedData         
2890                        break
2891                case 1:
2892                        DoAlert 0,"The current data has been added to the accumulated data. You can add more data."
2893                        Wave acc=accumulatedData
2894                        Wave cur=slicedData
2895                        acc += cur
2896                        break
2897                case 2:
2898                        DoAlert 0,"The accumulated data is now the display data and is ready for display or export."
2899                        Duplicate/O accumulatedData slicedData
2900                        // do something to "touch" the display to force it to update
2901                        NVAR gLog = root:Packages:NIST:VSANS:Event:gEvent_logint
2902                        V_LogIntEvent_Proc("",gLog)
2903                        break
2904                default:                       
2905                               
2906        endswitch
2907
2908        SetDataFolder root:
2909        return(0)
2910end
2911
2912
2913////////////////////////////////////////////
2914//
2915// Panel and procedures for decimation
2916//
2917////////////////////////////////////////////
2918
2919//Function E_ShowDecimateButton(ctrlName) : ButtonControl
2920//      String ctrlName
2921//
2922//      DoWindow/F DecimatePanel
2923//      if(V_flag ==0)
2924//              Execute "DecimatePanel()"
2925//      endif
2926//End
2927//
2928//
2929//Proc DecimatePanel() //: Panel
2930//     
2931//      PauseUpdate; Silent 1           // building window...
2932//      NewPanel /W=(1602,44,1961,380)/K=1
2933////    ShowTools/A
2934//      Button button0,pos={29,15},size={100,20},proc=SplitFileButtonProc,title="Split Big File"
2935//      SetVariable setvar0,pos={182,55},size={150,15},title="Decimation factor",fsize=10
2936//      SetVariable setvar0,limits={1,inf,1},value= root:Packages:NIST:VSANS:Event:gDecimation
2937//      Button button1,pos={26,245},size={150,20},proc=LoadDecimateButtonProc,title="Load and Decimate"
2938//      Button button2,pos={25,277},size={150,20},proc=ConcatenateButtonProc,title="Concatenate"
2939//      Button button3,pos={25,305},size={150,20},proc=DisplayConcatenatedButtonProc,title="Display Concatenated"
2940//      Button button4,pos={29,52},size={130,20},proc=Stream_LoadDecim,title="Load From List"
2941//     
2942//      GroupBox group0 title="Manual Controls",size={185,112},pos={14,220}
2943//EndMacro
2944
2945
2946Function V_SplitFileButtonProc(ctrlName) : ButtonControl
2947        String ctrlName
2948
2949        Execute "V_SplitBigFile()"
2950End
2951
2952
2953// show all of the data
2954//
2955Proc V_ShowDecimatedGraph()
2956
2957        DoWindow/F V_DecimatedGraph
2958        if(V_flag == 0)
2959                PauseUpdate; Silent 1           // building window...
2960                String fldrSav0= GetDataFolder(1)
2961                SetDataFolder root:Packages:NIST:VSANS:Event:
2962                Display /W=(25,44,486,356)/K=1/N=V_DecimatedGraph rescaledTime_dec
2963                SetDataFolder fldrSav0
2964                ModifyGraph mode=4
2965                ModifyGraph marker=19
2966                ModifyGraph rgb(rescaledTime_dec)=(0,0,0)
2967                ModifyGraph msize=1
2968                ErrorBars rescaledTime_dec OFF
2969                Label left "\\Z14Time (seconds)"
2970                Label bottom "\\Z14Event number"
2971                ShowInfo
2972        endif
2973       
2974EndMacro
2975
2976// data has NOT been processed
2977//
2978// so work with x,y,t, and rescaled time
2979// variables -- t_longest
2980Function V_ConcatenateButtonProc(ctrlName) : ButtonControl
2981        String ctrlName
2982       
2983        DoAlert 1,"Is this the first file?"
2984        Variable first = V_flag
2985       
2986        V_fConcatenateButton(first)
2987       
2988        return(0)
2989End
2990
2991Function V_fConcatenateButton(first)
2992        Variable first
2993
2994
2995        SetDataFolder root:Packages:NIST:VSANS:Event:
2996
2997        Wave timePt_dTmp=timePt_dTmp
2998        Wave xLoc_dTmp=xLoc_dTmp
2999        Wave yLoc_dTmp=yLoc_dTmp
3000        Wave rescaledTime_dTmp=rescaledTime_dTmp
3001       
3002        NVAR t_longest_dec = root:Packages:NIST:VSANS:Event:gEvent_t_longest_decimated
3003        NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
3004       
3005       
3006        if(first==1)            //1==yes, 2==no
3007                //then copy the files over, adjusting the time to start from zero
3008                // rescaledTime starts from zero (set by the loader)
3009
3010                timePt_dTmp -= timePt_dTmp[0]                   //subtract the first value
3011               
3012                Duplicate/O timePt_dTmp timePt_dec
3013                Duplicate/O xLoc_dTmp xLoc_dec
3014                Duplicate/O yLoc_dTmp yLoc_dec
3015                Duplicate/O rescaledTime_dTmp rescaledTime_dec
3016               
3017                t_longest_dec = t_longest
3018       
3019        else
3020                // concatenate the files + adjust the time
3021                Wave timePt_dec=timePt_dec
3022                Wave xLoc_dec=xLoc_dec
3023                Wave yLoc_dec=yLoc_dec
3024                Wave rescaledTime_dec=rescaledTime_dec
3025
3026                // adjust the times -- assuming they add
3027                // rescaledTime starts from zero (set by the loader)
3028                //
3029                //
3030                rescaledTime_dTmp += rescaledTime_dec[numpnts(rescaledTime_dec)-1]
3031                rescaledTime_dTmp += abs(rescaledTime_dec[numpnts(rescaledTime_dec)-1] - rescaledTime_dec[numpnts(rescaledTime_dec)-2])
3032               
3033                timePt_dTmp -= timePt_dTmp[0]                   //subtract the first value     
3034               
3035                timePt_dTmp += timePt_dec[numpnts(timePt_dec)-1]                // offset by the last point
3036                timePt_dTmp += abs(timePt_dec[numpnts(timePt_dec)-1] - timePt_dec[numpnts(timePt_dec)-2])               // plus delta so there's not a flat step
3037               
3038                Concatenate/NP/O {timePt_dec,timePt_dTmp}, tmp
3039                Duplicate/O tmp timePt_dec
3040               
3041                Concatenate/NP/O {xLoc_dec,xLoc_dTmp}, tmp
3042                Duplicate/O tmp xLoc_dec
3043               
3044                Concatenate/NP/O {yLoc_dec,yLoc_dTmp}, tmp
3045                Duplicate/O tmp yLoc_dec
3046               
3047                Concatenate/NP/O {rescaledTime_dec,rescaledTime_dTmp}, tmp
3048                Duplicate/O tmp rescaledTime_dec
3049               
3050
3051                KillWaves tmp
3052
3053                t_longest_dec = rescaledTime_dec[numpnts(rescaledTime_dec)-1]
3054
3055        endif
3056       
3057       
3058        SetDataFolder root:
3059       
3060        return(0)
3061
3062End
3063
3064Function V_DisplayConcatenatedButtonProc(ctrlName) : ButtonControl
3065        String ctrlName
3066
3067        //copy the files over to the display set for processing
3068        SetDataFolder root:Packages:NIST:VSANS:Event:
3069
3070        Wave timePt_dec=timePt_dec
3071        Wave xLoc_dec=xLoc_dec
3072        Wave yLoc_dec=yLoc_dec
3073        Wave rescaledTime_dec=rescaledTime_dec
3074               
3075        NVAR t_longest_dec = root:Packages:NIST:VSANS:Event:gEvent_t_longest_decimated
3076        NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
3077       
3078        Duplicate/O timePt_dec timePt
3079        Duplicate/O xLoc_dec xLoc
3080        Duplicate/O yLoc_dec yLoc
3081        Duplicate/O rescaledTime_dec rescaledTime
3082       
3083        t_longest = t_longest_dec       
3084       
3085        SetDataFolder root:
3086       
3087        return(0)
3088
3089End
3090
3091
3092
3093// unused, old testing procedure
3094Function V_LoadDecimateButtonProc(ctrlName) : ButtonControl
3095        String ctrlName
3096
3097        V_LoadEventLog_Button("")
3098       
3099        // now decimate
3100        SetDataFolder root:Packages:NIST:VSANS:Event:
3101
3102        Wave timePt=timePt
3103        Wave xLoc=xLoc
3104        Wave yLoc=yLoc
3105        NVAR t_longest_dec = root:Packages:NIST:VSANS:Event:gEvent_t_longest_decimated
3106
3107        NVAR decimation = root:Packages:NIST:VSANS:Event:gDecimation
3108
3109
3110        Duplicate/O timePt, timePt_dTmp
3111        Duplicate/O xLoc, xLoc_dTmp
3112        Duplicate/O yLoc, yLoc_dTmp
3113        Resample/DOWN=(decimation)/N=1 timePt_dTmp
3114        Resample/DOWN=(decimation)/N=1 xLoc_dTmp
3115        Resample/DOWN=(decimation)/N=1 yLoc_dTmp
3116
3117
3118        Duplicate/O timePt_dTmp rescaledTime_dTmp
3119        rescaledTime_dTmp = 1e-7*(timePt_dTmp - timePt_dTmp[0])         //convert to seconds and start from zero
3120        t_longest_dec = waveMax(rescaledTime_dTmp)              //should be the last point
3121
3122        SetDataFolder root:
3123
3124       
3125End
3126
3127
3128
3129
3130
3131
3132
3133////
3134//// loads a list of files, decimating each chunk as it is read in
3135////
3136//Function Stream_LoadDecim(ctrlName)
3137//      String ctrlName
3138//     
3139//      Variable fileref
3140//
3141//      SVAR filename = root:Packages:NIST:VSANS:Event:gEvent_logfile
3142//      NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
3143//
3144//      SVAR listStr = root:Packages:NIST:VSANS:Event:gSplitFileList
3145//      NVAR t_longest_dec = root:Packages:NIST:VSANS:Event:gEvent_t_longest_decimated
3146//      NVAR decimation = root:Packages:NIST:VSANS:Event:gDecimation
3147//
3148//      String pathStr
3149//      PathInfo catPathName
3150//      pathStr = S_Path
3151//
3152//// if "stream" mode is not checked - abort
3153//      NVAR gEventModeRadioVal= root:Packages:NIST:VSANS:Event:gEvent_mode
3154//      if(gEventModeRadioVal != MODE_STREAM)
3155//              Abort "The mode must be 'Stream' to use this function"
3156//              return(0)
3157//      endif
3158//
3159//// if the list has been edited, turn it into a list
3160//      WAVE/T/Z tw = root:Packages:NIST:VSANS:Event:SplitFileWave
3161//      if(WaveExists(tw))
3162//              listStr = TextWave2SemiList(tw)
3163//      else
3164//              ShowSplitFileTable()
3165//              DoAlert 0,"Enter the file names in the table, then click 'Load From List' again."
3166//              return(0)
3167//      endif
3168//     
3169//
3170//      //loop through everything in the list
3171//      Variable num,ii
3172//      num = ItemsInList(listStr)
3173//     
3174//      for(ii=0;ii<num;ii+=1)
3175//
3176//// (1) load the file, prepending the path             
3177//              filename = pathStr + StringFromList(ii, listStr  ,";")
3178//             
3179//
3180//#if (exists("EventLoadWave")==4)
3181//              LoadEvents_XOP()
3182//#else
3183//              LoadEvents()
3184//#endif       
3185//
3186//              SetDataFolder root:Packages:NIST:VSANS:Event:                   //LoadEvents sets back to root:
3187//
3188//              Wave timePt=timePt
3189//              Wave xLoc=xLoc
3190//              Wave yLoc=yLoc
3191//              CleanupTimes(xLoc,yLoc,timePt)          //remove zeroes
3192//
3193//              Duplicate/O timePt rescaledTime
3194//              rescaledTime = 1e-7*(timePt-timePt[0])          //convert to seconds and start from zero
3195//              t_longest = waveMax(rescaledTime)               //should be the last point
3196//             
3197//// (2) do the decimation, just on timePt. create rescaledTime from the decimated timePt       
3198//             
3199//              Duplicate/O timePt, timePt_dTmp
3200//              Duplicate/O xLoc, xLoc_dTmp
3201//              Duplicate/O yLoc, yLoc_dTmp
3202//              Resample/DOWN=(decimation)/N=1 timePt_dTmp
3203//              Resample/DOWN=(decimation)/N=1 xLoc_dTmp
3204//              Resample/DOWN=(decimation)/N=1 yLoc_dTmp
3205//     
3206//     
3207//              Duplicate/O timePt_dTmp rescaledTime_dTmp
3208//              rescaledTime_dTmp = 1e-7*(timePt_dTmp - timePt_dTmp[0])         //convert to seconds and start from zero
3209//              t_longest_dec = waveMax(rescaledTime_dTmp)              //should be the last point
3210//             
3211//
3212//// (3) concatenate
3213//              fConcatenateButton(ii+1)                //passes 1 for the first time, >1 each other time
3214//     
3215//      endfor
3216//
3217//////          Now that everything is decimated and concatenated, create the rescaled time wave
3218////    SetDataFolder root:Packages:NIST:VSANS:Event:                   //LoadEvents sets back to root:
3219////    Wave timePt_dec = timePt_dec
3220////    Duplicate/O timePt_dec rescaledTime_dec
3221////    rescaledTime_dec = 1e-7*(timePt_dec - timePt_dec[0])            //convert to seconds and start from zero
3222////    t_longest_dec = waveMax(rescaledTime_dec)               //should be the last point
3223//     
3224//      DisplayConcatenatedButtonProc("")
3225//     
3226//      SetDataFolder root:
3227//
3228//      return(0)
3229//End
3230//
3231//Function ShowList_ToLoad(ctrlName)
3232//      String ctrlName
3233//     
3234//      ShowSplitFileTable()
3235//     
3236//      return(0)
3237//End
3238
3239
3240////
3241//// loads a list of files that have been adjusted and saved
3242//// -- does not decimate
3243////
3244//Function Stream_LoadAdjustedList(ctrlName)
3245//      String ctrlName
3246//     
3247//      Variable fileref
3248//
3249//      SVAR filename = root:Packages:NIST:VSANS:Event:gEvent_logfile
3250//      NVAR t_longest = root:Packages:NIST:VSANS:Event:gEvent_t_longest
3251//
3252//      SVAR listStr = root:Packages:NIST:VSANS:Event:gSplitFileList
3253//      NVAR t_longest_dec = root:Packages:NIST:VSANS:Event:gEvent_t_longest_decimated
3254////    NVAR decimation = root:Packages:NIST:VSANS:Event:gDecimation
3255//
3256//      String pathStr
3257//      PathInfo catPathName
3258//      pathStr = S_Path
3259//
3260//// if "stream" mode is not checked - abort
3261//      NVAR gEventModeRadioVal= root:Packages:NIST:VSANS:Event:gEvent_mode
3262//      if(gEventModeRadioVal != MODE_STREAM)
3263//              Abort "The mode must be 'Stream' to use this function"
3264//              return(0)
3265//      endif
3266//
3267//// if the list has been edited, turn it into a list
3268//      WAVE/T/Z tw = root:Packages:NIST:VSANS:Event:SplitFileWave
3269//      if(WaveExists(tw))
3270//              listStr = TextWave2SemiList(tw)
3271//      else
3272//              ShowSplitFileTable()
3273//              DoAlert 0,"Enter the file names in the table, then click 'Load From List' again."
3274//              return(0)
3275//      endif
3276//     
3277//
3278//      //loop through everything in the list
3279//      Variable num,ii
3280//      num = ItemsInList(listStr)
3281//     
3282//      for(ii=0;ii<num;ii+=1)
3283//
3284//// (1) load the file, prepending the path             
3285//              filename = pathStr + StringFromList(ii, listStr  ,";")
3286//             
3287//              SetDataFolder root:Packages:NIST:VSANS:Event:
3288//              LoadWave/T/O fileName
3289//
3290//              SetDataFolder root:Packages:NIST:VSANS:Event:                   //LoadEvents sets back to root: ??
3291//
3292//// this is what is loaded -- _dec extension is what is concatenated, and will be copied back later
3293//              Wave timePt=timePt
3294//              Wave xLoc=xLoc
3295//              Wave yLoc=yLoc
3296//              Wave rescaledTime=rescaledTime
3297//
3298////            CleanupTimes(xLoc,yLoc,timePt)          //remove zeroes
3299//
3300////            Duplicate/O timePt rescaledTime
3301////            rescaledTime = 1e-7*(timePt-timePt[0])          //convert to seconds and start from zero
3302////            t_longest = waveMax(rescaledTime)               //should be the last point
3303//             
3304//// (2) No decimation
3305//             
3306//              Duplicate/O timePt, timePt_dTmp
3307//              Duplicate/O xLoc, xLoc_dTmp
3308//              Duplicate/O yLoc, yLoc_dTmp
3309//              Duplicate/O rescaledTime, rescaledTime_dTmp
3310//
3311//
3312//// (3) concatenate
3313//              fConcatenateButton(ii+1)                //passes 1 for the first time, >1 each other time
3314//     
3315//      endfor
3316//     
3317//      DisplayConcatenatedButtonProc("")               // this resets the longest time, too
3318//             
3319//      SetDataFolder root:
3320//
3321//      return(0)
3322//End
3323//
3324///////////////////////////////////////
3325//
3326//// dd-mon-yyyy hh:mm:ss -> Event file name
3327//// the VAX uses 24 hr time for hh
3328////
3329//// scans as string elements since I'm reconstructing a string name
3330//Function/S DateAndTime2HSTName(dateandtime)
3331//      string dateAndTime
3332//     
3333//      String day,yr,hh,mm,ss,time_secs
3334//      Variable mon
3335//      string str,monStr,fileStr
3336//     
3337//      str=dateandtime
3338//      sscanf str,"%2s-%3s-%4s %2s:%2s:%2s",day,monStr,yr,hh,mm,ss
3339//      mon = monStr2num(monStr)
3340//
3341//      fileStr = "Event"+yr+num2str(mon)+day+hh+mm+ss+".hst"
3342//      Print fileStr
3343//
3344//      return(fileStr)
3345//end
3346//
3347//// dd-mon-yyyy hh:mm:ss -> Event file name
3348//// the VAX uses 24 hr time for hh
3349////
3350//// scans as string elements since I'm reconstructing a string name
3351//Function DateAndTime2HSTNumber(dateandtime)
3352//      string dateAndTime
3353//     
3354//      String day,yr,hh,mm,ss,time_secs
3355//      Variable mon,num
3356//      string str,monStr,fileStr
3357//     
3358//      str=dateandtime
3359//      sscanf str,"%2s-%3s-%4s %2s:%2s:%2s",day,monStr,yr,hh,mm,ss
3360//      mon = monStr2num(monStr)
3361//
3362//      fileStr = yr+num2str(mon)+day+hh+mm+ss
3363//      num = str2num(fileStr)
3364//
3365//      return(num)
3366//end
3367//
3368//Function HSTName2Num(str)
3369//      String str
3370//     
3371//      Variable num
3372//      sscanf str,"Event%d.hst",num
3373//      return(num)
3374//end
3375///////////////////////////////
Note: See TracBrowser for help on using the repository browser.