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

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

updating the IgorVersion? pragma to v7.0 for all files to be consistent.

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

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