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

Last change on this file since 1046 was 1046, checked in by srkline, 6 years ago

changes to properly read and decode VSANS event files, and to process them with a trimmed down (and to be customized) version of the event mode panel.

currently reading and decoding is done without an XOP since the file structure is much simpler than ordela.

TOF mode data can be processed - as this will be needed initially at VSANS to be able to calibrate the wavelength.

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