source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/SANS/EventModeProcessing.ipf @ 874

Last change on this file since 874 was 874, checked in by srkline, 10 years ago

Changes to the EventModeProcessing? to put some of the functions on the panel as buttons, rather than on the Macros menu.

Added a menu item in the package loader to invoke the event panel. The reduction procedures must be loaded first.

Added Matt's fixes to the rescaling panel so that it will remove the "_RA" suffix when the scaling is reset to I vs q. A benefit of this is that the dependency works again (automatically) - so users could toggle between scalings and adjust coefficients if they desired.

File size: 34.7 KB
Line 
1#pragma rtGlobals=1             // Use modern global access method.
2#pragma IgorVersion=6.1
3
4//#include "TISANE"
5
6
7// TODO:
8//
9// -- fix the log/lin display - it's not working correctly
10// X- add controls to show the bar graph
11// x- add popup for selecting the binning type
12// x- add ability to save the slices to RAW VAX files
13// X- add control to show the bin counts and bin end times
14// x- ADD buttons, switches, etc for the oscillatory mode - so that this can be accessed
15//
16// x- How are the headers filled for the VAX files from Teabag???
17// -- I currently read the events 2x. Once to count the events to make the waves the proper
18//     size, then a second time to actualy process the events. Would it be faster to insert points
19//     as needed, or to estimate the size, and make it too large, then trim at the end...
20// ((( NO -- deleting the extra zeros at the end is WAY WAY slower - turns 2sec into 100 sec)))
21//
22//
23//
24// -- for the 19 MB file - the max time is reported as 67.108s, but the max rescaled time = 61 s
25//    based on the last point... there are "spikes" in the time! -- look at the plot in the
26//    data browser... (so waveMax() gives a different answer than the end point, and BinarySearch()
27//    doesn't have a monotonic file to work with... ugh.)
28//
29//
30//
31// differentiate may be useful at some point, but not sure
32//¥Differentiate rescaledTime/D=rescaledTime_DIF
33//¥Display rescaledTime,rescaledTime_DIF
34//
35//
36
37
38
39Proc Show_Event_Panel()
40        DoWindow/F EventModePanel
41        if(V_flag ==0)
42                Init_Event()
43                EventModePanel()
44        EndIf
45End
46
47
48Function Init_Event()
49        String/G        root:Packages:NIST:gEvent_logfile
50        String/G        root:Packages:NIST:gEventDisplayString="Details of the file load"
51       
52        Variable/G      root:Packages:NIST:AIMTYPE_XY=0 // XY Event
53        Variable/G      root:Packages:NIST:AIMTYPE_XYM=2 // XY Minor event
54        Variable/G      root:Packages:NIST:AIMTYPE_MIR=1 // Minor rollover event
55        Variable/G      root:Packages:NIST:AIMTYPE_MAR=3 // Major rollover event
56
57        Variable/G root:Packages:NIST:gEvent_time_msw = 0
58        Variable/G root:Packages:NIST:gEvent_time_lsw = 0
59        Variable/G root:Packages:NIST:gEvent_t_longest = 0
60
61        Variable/G root:Packages:NIST:gEvent_tsdisp //Displayed slice
62        Variable/G root:Packages:NIST:gEvent_nslices = 10  //Number of time slices
63        Variable/G root:Packages:NIST:gEvent_slicewidth  = 1000 // slice width (us)
64       
65        Variable/G root:Packages:NIST:gEvent_prescan // Do we prescan the file?
66        Variable/G root:Packages:NIST:gEvent_logint = 1
67
68        Variable/G root:Packages:NIST:gEvent_Mode = 1           // ==0 for "stream", ==1 for Oscillatory
69
70        NVAR nslices = root:Packages:NIST:gEvent_nslices
71       
72        SetDataFolder root:
73        NewDataFolder/O/S root:Packages:NIST:Event
74       
75        Make/D/O/N=(XBINS,YBINS,nslices) slicedData
76        Duplicate/O slicedData logslicedData
77        Duplicate/O slicedData dispsliceData
78       
79        SetDataFolder root:
80End
81
82Proc EventModePanel()
83        PauseUpdate; Silent 1           // building window...
84        NewPanel /W=(100,50,600,840)/N=EventModePanel/K=2
85        DoWindow/C EventModePanel
86        ModifyPanel fixedSize=1,noEdit =1
87        //ShowTools/A
88        SetDrawLayer UserBack
89        Button button0,pos={10,10}, size={150,20},title="Load Event Log File",fSize=12
90        Button button0,proc=LoadEventLog_Button
91       
92        TitleBox tb1,pos={20,650},size={460,80},fSize=12
93        TitleBox tb1,variable=root:Packages:NIST:gEventDisplayString
94       
95        CheckBox chkbox1,pos={170,15},title="Oscillatory Mode?"
96        CheckBox chkbox1,variable = root:Packages:NIST:gEvent_mode
97        Button doneButton,pos={435,12}, size={50,20},title="Done",fSize=12
98        Button doneButton,proc=EventDone_Proc
99
100        Button button2,pos={20,122},size={140,20},proc=ShowEventDataButtonProc,title="Show Event Data"
101        Button button3,pos={20,147},size={140,20},proc=ShowBinDetailsButtonProc,title="Show Bin Details"
102        Button button4,pos={175,122},size={140,20},proc=UndoTimeSortButtonProc,title="Undo Time Sort"
103        Button button5,pos={175,147},size={140,20},proc=ExportSlicesButtonProc,title="Export Slices as VAX"
104        Button button6,pos={378,13},size={40,20},proc=EventModeHelpButtonProc,title="?"
105       
106        //DrawLine 10,35,490,35
107        Button button1,pos = {10,50}, size={150,20},title="Process Data",fSize=12
108        Button button1,proc=ProcessEventLog_Button
109        SetVariable setvar1,pos={170,50},size={160,20},title="Number of slices",fSize=12
110        SetVariable setvar1,value=root:Packages:NIST:gEvent_nslices
111        SetVariable setvar2,pos={330,50},size={160,20},title="Max Time (s)",fSize=12
112        SetVariable setvar2,value=root:Packages:NIST:gEvent_t_longest
113        //DrawLine 10,65,490,65
114       
115//      PopupMenu popup0 title="Bin Spacing",pos={150,90},value="Equal;Fibonacci;Log;"
116        PopupMenu popup0 title="Bin Spacing",pos={150,90},value="Equal;Fibonacci;"
117       
118        CheckBox chkbox2,pos={20,95},title="Log Intensity",value=1
119        CheckBox chkbox2,variable=root:Packages:NIST:gEvent_logint,proc=LogIntEvent_Proc
120        SetVariable setvar0,pos={320,90},size={160,20},title="Display Time Slice",fSize=12
121        SetVariable setvar0,value= root:Packages:NIST:gEvent_tsdisp
122        SetVariable setvar0,proc=sliceSelectEvent_Proc
123        Display/W=(20,180,480,640)/HOST=EventModePanel/N=Event_slicegraph
124        AppendImage/W=EventModePanel#Event_slicegraph/T root:Packages:NIST:Event:dispsliceData
125        ModifyImage/W=EventModePanel#Event_slicegraph  ''#0 ctab= {*,*,Grays,0}
126        ModifyImage/W=EventModePanel#Event_slicegraph ''#0 ctabAutoscale=3
127        ModifyGraph margin(left)=14,margin(bottom)=14,margin(top)=14,margin(right)=14
128        ModifyGraph mirror=2
129        ModifyGraph nticks=4
130        ModifyGraph minor=1
131        ModifyGraph fSize=9
132        ModifyGraph standoff=0
133        ModifyGraph tkLblRot(left)=90
134        ModifyGraph btLen=3
135        ModifyGraph tlOffset=-2
136        SetAxis/A left
137        SetActiveSubwindow ##
138EndMacro
139
140Function ShowEventDataButtonProc(ba) : ButtonControl
141        STRUCT WMButtonAction &ba
142
143        switch( ba.eventCode )
144                case 2: // mouse up
145                        // click code here
146                        Execute "ShowRescaledTimeGraph()"
147                        break
148                case -1: // control being killed
149                        break
150        endswitch
151
152        return 0
153End
154
155Function ShowBinDetailsButtonProc(ba) : ButtonControl
156        STRUCT WMButtonAction &ba
157
158        switch( ba.eventCode )
159                case 2: // mouse up
160                        // click code here
161                        Execute "ShowBinTable()"
162                        Execute "BinEventBarGraph()"
163                        break
164                case -1: // control being killed
165                        break
166        endswitch
167
168        return 0
169End
170
171Function UndoTimeSortButtonProc(ba) : ButtonControl
172        STRUCT WMButtonAction &ba
173
174        switch( ba.eventCode )
175                case 2: // mouse up
176                        // click code here
177                        Execute "UndoTheSorting()"
178                        break
179                case -1: // control being killed
180                        break
181        endswitch
182
183        return 0
184End
185
186Function ExportSlicesButtonProc(ba) : ButtonControl
187        STRUCT WMButtonAction &ba
188
189        switch( ba.eventCode )
190                case 2: // mouse up
191                        // click code here
192                        Execute "ExportSlicesAsVAX()"           //will invoke the dialog
193                        break
194                case -1: // control being killed
195                        break
196        endswitch
197
198        return 0
199End
200
201Function EventModeHelpButtonProc(ba) : ButtonControl
202        STRUCT WMButtonAction &ba
203
204        switch( ba.eventCode )
205                case 2: // mouse up
206                        // click code here
207                        DoAlert 0,"The help file has not been written yet"
208                        break
209                case -1: // control being killed
210                        break
211        endswitch
212
213        return 0
214End
215
216
217Function EventDone_Proc(ba) : ButtonControl
218        STRUCT WMButtonAction &ba
219       
220        String win = ba.win
221        switch (ba.eventCode)
222                case 2:
223                        DoWindow/K EventModePanel
224                        break
225        endswitch
226        return(0)
227End
228
229
230
231Function ProcessEventLog_Button(ctrlName) : ButtonControl
232        String ctrlName
233       
234        NVAR mode=root:Packages:NIST:gEvent_Mode
235       
236        if(mode == 0)
237                Stream_ProcessEventLog("")
238        endif
239       
240        if(mode == 1)
241                Osc_ProcessEventLog("")
242        endif
243       
244        return(0)
245end
246
247// for oscillatory mode
248//
249Function Osc_ProcessEventLog(ctrlName)
250        String ctrlName
251
252
253        Make/O/D/N=(128,128) root:Packages:NIST:Event:binnedData
254       
255        Wave binnedData = root:Packages:NIST:Event:binnedData
256        Wave xLoc = root:Packages:NIST:Event:xLoc
257        Wave yLoc = root:Packages:NIST:Event:yLoc
258
259        SetDataFolder root:Packages:NIST:Event
260        IndexForHistogram(xLoc,yLoc,binnedData)
261        SetDataFolder root:
262        Wave index = root:Packages:NIST:Event:SavedIndex
263       
264        JointHistogram(xLoc,yLoc,binnedData,index)              // puts everything into one array
265
266
267// now with the number of slices and max time, process the events
268        Osc_ProcessEvents(xLoc,yLoc,index)
269
270
271        SetDataFolder root:Packages:NIST:Event:
272
273        SetDataFolder root:
274
275        return(0)
276End
277
278
279Function Stream_ProcessEventLog(ctrlName)
280        String ctrlName
281
282//      NVAR slicewidth = root:Packages:NIST:gTISANE_slicewidth
283
284       
285        Make/O/D/N=(128,128) root:Packages:NIST:Event:binnedData
286       
287        Wave binnedData = root:Packages:NIST:Event:binnedData
288        Wave xLoc = root:Packages:NIST:Event:xLoc
289        Wave yLoc = root:Packages:NIST:Event:yLoc
290
291        SetDataFolder root:Packages:NIST:Event
292        IndexForHistogram(xLoc,yLoc,binnedData)
293        SetDataFolder root:
294        Wave index = root:Packages:NIST:Event:SavedIndex
295       
296        JointHistogram(xLoc,yLoc,binnedData,index)              // puts everything into one array
297
298
299// now with the number of slices and max time, process the events
300        Stream_ProcessEvents(xLoc,yLoc,index)
301
302
303        SetDataFolder root:Packages:NIST:Event:
304
305        SetDataFolder root:
306
307        return(0)
308End
309
310
311Proc    UndoTheSorting()
312        Osc_UndoSort()
313End
314
315// for oscillatory mode
316//
317// -- this takes the previously generated index, and un-sorts the data to restore to the
318// "as-collected" state
319//
320Function Osc_UndoSort()
321
322        SetDataFolder root:Packages:NIST:Event          //don't count on the folder remaining here
323        Wave rescaledTime = rescaledTime
324        Wave OscSortIndex = OscSortIndex
325        Wave yLoc = yLoc
326        Wave xLoc = xLoc
327        Wave timePt = timePt
328
329        Sort OscSortIndex OscSortIndex,yLoc,xLoc,timePt,rescaledTime
330
331        KillWaves/Z OscSortIndex
332       
333        SetDataFolder root:
334        return(0)
335End
336
337// for oscillatory mode
338//
339//// use indexSort to be able to restore the original data
340//¥Duplicate rescaledTime OscSortIndex
341//¥MakeIndex rescaledTime OscSortIndex
342//¥IndexSort OscSortIndex, yLoc,xLoc,timePt,rescaledTime
343//¥Sort OscSortIndex OscSortIndex,yLoc,xLoc,timePt,rescaledTime
344//
345// sort the data by time, then do the binning
346// save an index to be able to "undo" the sorting
347//
348Function Osc_ProcessEvents(xLoc,yLoc,index)
349        Wave xLoc,yLoc,index
350       
351        NVAR t_longest = root:Packages:NIST:gEvent_t_longest
352        NVAR nslices = root:Packages:NIST:gEvent_nslices
353
354        SetDataFolder root:Packages:NIST:Event          //don't count on the folder remaining here
355       
356        Make/D/O/N=(XBINS,YBINS,nslices) slicedData
357               
358        Wave slicedData = slicedData
359        Wave rescaledTime = rescaledTime
360        Wave timePt = timePt
361        Make/O/D/N=(128,128) tmpData
362        Make/O/D/N=(nslices+1) binEndTime,binCount
363        Wave binEndTime = binEndTime
364        Wave binCount = binCount
365
366        variable ii,del,p1,p2,t1,t2
367        del = t_longest/nslices
368
369        slicedData = 0
370        binEndTime[0]=0
371        BinCount[nslices]=0
372
373
374        String binTypeStr=""
375        ControlInfo /W=EventModePanel popup0
376        binTypeStr = S_value
377       
378        strswitch(binTypeStr)   // string switch
379                case "Equal":           // execute if case matches expression
380                        SetLinearBins(binEndTime,nslices,t_longest)
381                        break                                           // exit from switch
382                case "Fibonacci":               // execute if case matches expression
383                        SetFibonacciBins(binEndTime,nslices,t_longest)
384                        break
385                case "Log":             // execute if case matches expression
386                        SetLogBins(binEndTime,nslices,t_longest)
387                        break
388                default:                                                        // optional default expression executed
389                        DoAlert 0,"No match for bin type, Equal bins used"
390                        SetLinearBins(binEndTime,nslices,t_longest)
391        endswitch
392
393
394// now before binning, sort the data
395
396        //this is slow - undoing the sorting and starting over, but if you don't,
397        // you'll never be able to undo the sort
398        //
399        SetDataFolder root:Packages:NIST:Event:
400
401        if(WaveExists($"root:Packages:NIST:Event:OscSortIndex") == 0 )
402                Duplicate/O rescaledTime OscSortIndex
403                MakeIndex rescaledTime OscSortIndex
404                IndexSort OscSortIndex, yLoc,xLoc,timePt,rescaledTime   
405        Endif
406       
407        for(ii=0;ii<nslices;ii+=1)
408                if(ii==0)
409//                      t1 = ii*del
410//                      t2 = (ii+1)*del
411                        p1 = BinarySearch(rescaledTime,0)
412                        p2 = BinarySearch(rescaledTime,binEndTime[ii+1])
413                else
414//                      t2 = (ii+1)*del
415                        p1 = p2+1               //one more than the old one
416                        p2 = BinarySearch(rescaledTime,binEndTime[ii+1])               
417                endif
418
419        // typically zero will never be a valid time value in oscillatory mode. in "stream" mode, the first is normalized to == 0
420        // but not here - times are what they are.
421                if(p1 == -1)
422                        Printf "p1 = -1 Binary search off the end %15.10g <?? %15.10g\r", 0, rescaledTime[0]
423                        p1 = 0          //set to the first point if it's off the end
424                Endif
425               
426                if(p2 == -2)
427                        Printf "p2 = -2 Binary search off the end %15.10g >?? %15.10g\r", binEndTime[ii+1], rescaledTime[numpnts(rescaledTime)-1]
428                        p2 = numpnts(rescaledTime)-1            //set to the last point if it's off the end
429                Endif
430                Print p1,p2
431
432
433                tmpData=0
434                JointHistogramWithRange(xLoc,yLoc,tmpData,index,p1,p2)
435                slicedData[][][ii] = tmpData[p][q]
436               
437//              binEndTime[ii+1] = t2
438                binCount[ii] = sum(tmpData,-inf,inf)
439        endfor
440
441        Duplicate/O slicedData,root:Packages:NIST:Event:dispsliceData,root:Packages:NIST:Event:logSlicedData
442        Wave logSlicedData = root:Packages:NIST:Event:logSlicedData
443        logslicedData = log(slicedData)
444
445        SetDataFolder root:
446        return(0)
447End
448
449
450// for the mode of "one continuous exposure"
451//
452Function Stream_ProcessEvents(xLoc,yLoc,index)
453        Wave xLoc,yLoc,index
454       
455        NVAR t_longest = root:Packages:NIST:gEvent_t_longest
456        NVAR nslices = root:Packages:NIST:gEvent_nslices
457
458        SetDataFolder root:Packages:NIST:Event          //don't count on the folder remaining here
459       
460        Make/D/O/N=(XBINS,YBINS,nslices) slicedData
461               
462        Wave slicedData = slicedData
463        Wave rescaledTime = rescaledTime
464        Make/O/D/N=(128,128) tmpData
465        Make/O/D/N=(nslices+1) binEndTime,binCount//,binStartTime
466        Wave binEndTime = binEndTime
467//      Wave binStartTime = binStartTime
468        Wave binCount = binCount
469
470        variable ii,del,p1,p2,t1,t2
471        del = t_longest/nslices
472
473        slicedData = 0
474        binEndTime[0]=0
475        BinCount[nslices]=0
476       
477        String binTypeStr=""
478        ControlInfo /W=EventModePanel popup0
479        binTypeStr = S_value
480       
481        strswitch(binTypeStr)   // string switch
482                case "Equal":           // execute if case matches expression
483                        SetLinearBins(binEndTime,nslices,t_longest)
484                        break                                           // exit from switch
485                case "Fibonacci":               // execute if case matches expression
486                        SetFibonacciBins(binEndTime,nslices,t_longest)
487                        break
488                case "Log":             // execute if case matches expression
489                        SetLogBins(binEndTime,nslices,t_longest)
490                        break
491                default:                                                        // optional default expression executed
492                        DoAlert 0,"No match for bin type, Equal bins used"
493                        SetLinearBins(binEndTime,nslices,t_longest)
494        endswitch
495       
496        for(ii=0;ii<nslices;ii+=1)
497                if(ii==0)
498//                      t1 = ii*del
499//                      t2 = (ii+1)*del
500                        p1 = BinarySearch(rescaledTime,0)
501                        p2 = BinarySearch(rescaledTime,binEndTime[ii+1])
502                else
503//                      t2 = (ii+1)*del
504                        p1 = p2+1               //one more than the old one
505                        p2 = BinarySearch(rescaledTime,binEndTime[ii+1])               
506                endif
507
508                if(p1 == -1)
509                        Printf "p1 = -1 Binary search off the end %15.10g <?? %15.10g\r", 0, rescaledTime[0]
510                        p1 = 0          //set to the first point if it's off the end
511                Endif
512                if(p2 == -2)
513                        Printf "p2 = -2 Binary search off the end %15.10g >?? %15.10g\r", binEndTime[ii+1], rescaledTime[numpnts(rescaledTime)-1]
514                        p2 = numpnts(rescaledTime)-1            //set to the last point if it's off the end
515                Endif
516                Print p1,p2
517
518
519                tmpData=0
520                JointHistogramWithRange(xLoc,yLoc,tmpData,index,p1,p2)
521                slicedData[][][ii] = tmpData[p][q]
522               
523//              binEndTime[ii+1] = t2
524                binCount[ii] = sum(tmpData,-inf,inf)
525        endfor
526
527        Duplicate/O slicedData,root:Packages:NIST:Event:dispsliceData,root:Packages:NIST:Event:logSlicedData
528        Wave logSlicedData = root:Packages:NIST:Event:logSlicedData
529        logslicedData = log(slicedData)
530
531        SetDataFolder root:
532        return(0)
533End
534
535Function SetLinearBins(binEndTime,nslices,t_longest)
536        Wave binEndTime
537        Variable nslices,t_longest
538
539        Variable del,ii,t2
540        binEndTime[0]=0         //so the bar graph plots right...
541        del = t_longest/nslices
542       
543        for(ii=0;ii<nslices;ii+=1)
544                t2 = (ii+1)*del
545                binEndTime[ii+1] = t2
546        endfor
547        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
548
549        return(0)       
550End
551
552
553Function SetLogBins(binEndTime,nslices,t_longest)
554        Wave binEndTime
555        Variable nslices,t_longest
556
557        Variable tMin,ii
558
559        Wave rescaledTime = root:Packages:NIST:Event:rescaledTime
560       
561        binEndTime[0]=0         //so the bar graph plots right...
562
563        // just like the log-scaled q-points
564        tMin = rescaledTime[1]/1                        //just a guess... can't use tMin=0, and rescaledTime[0] == 0 by definition
565        Print rescaledTime[1], tMin
566        for(ii=0;ii<nslices;ii+=1)
567                binEndTime[ii+1] =alog(log(tMin) + (ii+1)*((log(t_longest)-log(tMin))/nslices))
568        endfor
569        binEndTime[ii+1] = t_longest            //otherwise floating point errors such that the last time point is off the end of the Binary search
570       
571        return(0)
572End
573
574Function MakeFibonacciWave(w,num)
575        Wave w
576        Variable num
577
578        //skip the initial zero
579        Variable f1,f2,ii
580        f1=1
581        f2=1
582        w[0] = f1
583        w[1] = f2
584        for(ii=2;ii<num;ii+=1)
585                w[ii] = f1+f2
586                f1=f2
587                f2=w[ii]
588        endfor
589               
590        return(0)
591end
592
593Function SetFibonacciBins(binEndTime,nslices,t_longest)
594        Wave binEndTime
595        Variable nslices,t_longest
596
597        Variable tMin,ii,total,t2,tmp
598        Make/O/D/N=(nslices) fibo
599        fibo=0
600        MakeFibonacciWave(fibo,nslices)
601       
602//      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}
603
604        binEndTime[0]=0         //so the bar graph plots right...
605        total = sum(fibo,0,nslices-1)           //total number of "pieces"
606       
607        tmp=0
608        for(ii=0;ii<nslices;ii+=1)
609                t2 = sum(fibo,0,ii)/total*t_longest
610                binEndTime[ii+1] = t2
611        endfor
612        binEndTime[ii+1] = t_longest            //otherwise floating point errors such that the last time point is off the end of the Binary search
613       
614        return(0)
615End
616
617
618
619
620Function LoadEventLog_Button(ctrlName) : ButtonControl
621        String ctrlName
622
623        NVAR mode=root:Packages:NIST:gEvent_mode
624       
625        if(mode == 0)
626                Stream_LoadEventLog("")
627        endif
628       
629        if(mode == 1)
630                Osc_LoadEventLog("")
631        endif
632       
633        return(0)
634End
635
636// for the mode of "one continuous exposure"
637//
638Function Stream_LoadEventLog(ctrlName)
639        String ctrlName
640       
641        Variable fileref
642
643        SVAR filename = root:Packages:NIST:gEvent_logfile
644        NVAR prescan = root:Packages:NIST:gEvent_prescan
645//      NVAR slicewidth = root:Packages:NIST:gEvent_slicewidth
646        NVAR nslices = root:Packages:NIST:gEvent_nslices
647        NVAR t_longest = root:Packages:NIST:gEvent_t_longest
648       
649        String fileFilters = "All Files:.*;Data Files (*.txt):.txt;"
650       
651        Open/R/D/F=fileFilters fileref
652        filename = S_filename
653       
654        LoadEvents()
655       
656        SetDataFolder root:Packages:NIST:Event:
657
658tic()
659        Wave timePt=timePt
660        Wave xLoc=xLoc
661        Wave yLoc=yLoc
662        CleanupTimes(xLoc,yLoc,timePt)          //remove zeroes
663       
664toc()
665
666        Duplicate/O timePt rescaledTime
667        rescaledTime = 1e-7*(timePt-timePt[0])          //convert to seconds and start from zero
668        t_longest = waveMax(rescaledTime)               //should be the last point
669
670        SetDataFolder root:
671
672        return(0)
673End
674
675// for the mode "oscillatory"
676//
677Function Osc_LoadEventLog(ctrlName)
678        String ctrlName
679       
680        Variable fileref
681
682        SVAR filename = root:Packages:NIST:gEvent_logfile
683        NVAR prescan = root:Packages:NIST:gEvent_prescan
684//      NVAR slicewidth = root:Packages:NIST:gEvent_slicewidth
685        NVAR nslices = root:Packages:NIST:gEvent_nslices
686        NVAR t_longest = root:Packages:NIST:gEvent_t_longest
687       
688        String fileFilters = "All Files:.*;Data Files (*.txt):.txt;"
689       
690        Open/R/D/F=fileFilters fileref
691        filename = S_filename
692       
693        LoadEvents()
694       
695        SetDataFolder root:Packages:NIST:Event:
696
697        Wave timePt=timePt
698        Wave xLoc=xLoc
699        Wave yLoc=yLoc
700        CleanupTimes(xLoc,yLoc,timePt)          //remove zeroes
701       
702        Duplicate/O timePt rescaledTime
703        rescaledTime *= 1e-7                    //convert to seconds and that's all
704        t_longest = waveMax(rescaledTime)               //won't be the last point, so get it this way
705
706        KillWaves/Z OscSortIndex                        //to make sure that there is no old index hanging around
707
708        SetDataFolder root:
709
710        return(0)
711End
712
713
714
715Function CleanupTimes(xLoc,yLoc,timePt)
716        Wave xLoc,yLoc,timePt
717
718        // start at the back and remove zeros
719        Variable num=numpnts(xLoc),ii
720       
721        ii=num
722        do
723                ii -= 1
724                if(timePt[ii] == 0 && xLoc[ii] == 0 && yLoc[ii] == 0)
725                        DeletePoints ii, 1, xLoc,yLoc,timePt
726                endif
727        while(timePt[ii-1] == 0 && xLoc[ii-1] == 0 && yLoc[ii-1] == 0)
728       
729        return(0)
730End
731
732Function LogIntEvent_Proc(ctrlName,checked) : CheckBoxControl
733        String ctrlName
734        Variable checked
735               
736        SetDataFolder root:Packages:NIST:Event
737        if(checked)
738                Duplicate/O logslicedData dispsliceData
739        else
740                Duplicate/O slicedData dispsliceData
741        endif
742
743        SetDataFolder root:
744End
745
746
747
748
749Function sliceSelectEvent_Proc(ctrlName, varNum, varStr, varName) : SetVariableControl
750        String ctrlName
751        Variable varNum
752        String varStr
753        String varName
754       
755        NVAR nslices = root:Packages:NIST:gEvent_nslices
756        NVAR selectedslice = root:Packages:NIST:gEvent_tsdisp
757       
758        if(varNum < 0)
759                selectedslice = 0
760                DoUpdate
761        elseif (varNum > nslices-1)
762                selectedslice = nslices-1
763                DoUpdate
764        else
765                ModifyImage/W=EventModePanel#Event_slicegraph ''#0 plane = varNum
766        endif
767
768End
769
770
771//
772// for the bit shifts, see the decimal-binary conversion
773// http://www.binaryconvert.com/convert_unsigned_int.html
774//
775Function LoadEvents()
776       
777        NVAR time_msw = root:Packages:NIST:gEvent_time_msw
778        NVAR time_lsw = root:Packages:NIST:gEvent_time_lsw
779        NVAR t_longest = root:Packages:NIST:gEvent_t_longest
780       
781        SVAR filepathstr = root:Packages:NIST:gEvent_logfile
782        SVAR dispStr = root:Packages:NIST:gEventDisplayString
783       
784        SetDataFolder root:Packages:NIST:Event
785
786        Variable fileref
787        String buffer
788        Variable dataval,timeval,type,numLines,verbose,verbose3
789        Variable xval,yval,rollBit,nRoll,roll_time
790        Variable Xmax, yMax
791        xMax = 127              // number the detector from 0->127
792        yMax = 127
793       
794        verbose3 = 1
795        verbose = 0
796        numLines = 0
797
798// this gets me the number of lines. not terribly useful       
799//      Open/R fileref as filepathstr
800//      do
801//              numLines += 1
802//              FReadLine fileref, buffer
803//              if (strlen(buffer) == 0)
804//                      numLines -= 1                   //last FReadLine wasn't really a line
805//                      break
806//              endif
807//      while(1)
808//      Close fileref
809       
810        // what I really need is the number of XY events
811        Variable numXYevents,num1,num2,num3,num0,totBytes
812        numXYevents = 0
813        num0 = 0
814        num1 = 0
815        num2 = 0
816        num3 = 0
817
818//tic()
819        Open/R fileref as filepathstr
820                FStatus fileref
821        Close fileref
822
823        totBytes = V_logEOF
824        Print "total bytes = ", totBytes
825       
826//toc()
827//
828        tic()
829       
830        Open/R fileref as filepathstr
831        do
832                do
833                        FReadLine fileref, buffer                       //skip the "blank" lines that have one character
834                while(strlen(buffer) == 1)             
835
836                if (strlen(buffer) == 0)
837                        break
838                endif
839               
840                sscanf buffer,"%x",dataval
841               
842                // two most sig bits (31-30)
843                type = (dataval & 0xC0000000)/1073741824                //right shift by 2^30
844               
845                if(type == 0)
846                        num0 += 1
847                        numXYevents += 1
848                endif
849                if(type == 2)
850                        num2 += 1
851                        numXYevents += 1
852                endif
853                if(type == 1)
854                        num1 += 1
855                endif
856                if(type == 3)
857                        num3 += 1
858                endif   
859               
860        while(1)
861        Close fileref
862//              done counting the number of XY events
863
864        toc()
865//
866//     
867//      Printf "numXYevents = %d\r",numXYevents
868//      Printf "XY = num0 = %d\r",num0
869//      Printf "XY time = num2 = %d\r",num2
870//      Printf "time MSW = num1 = %d\r",num1
871//      Printf "Rollover = num3 = %d\r",num3
872
873//      Printf "num0 + num2 = %d\r",num0+num2
874
875        String fileStr = ParseFilePath(0, filepathstr, ":", 1, 0),tmpStr
876       
877        sprintf tmpStr, "%s: %d total bytes",fileStr,totBytes
878        dispStr = tmpStr
879        sPrintf tmpStr,"\rnumXYevents = %d\rXY = num0 = %d",numXYevents,num0
880        dispStr += tmpStr
881        sPrintf tmpStr,"\rXY time = num2 = %d\rtime MSW = num1 = %d",num2,num1
882        dispStr += tmpStr
883        sPrintf tmpStr,"\rRollover = num3 = %d",num3
884        dispStr += tmpStr
885
886       
887       
888        Make/O/U/N=(numXYevents) xLoc,yLoc
889        Make/O/D/N=(numXYevents) timePt
890//      Make/O/U/N=(totBytes/4) xLoc,yLoc               //too large, trim when done (bad idea)
891//      Make/O/D/N=(totBytes/4) timePt
892        xLoc=0
893        yLoc=0
894        timePt=0
895
896       
897        Variable ii=0
898        nRoll = 0               //number of rollover events
899        roll_time = 2^26                //units of 10-7 sec
900       
901        time_msw=0
902       
903        tic()
904       
905        Open/R fileref as filepathstr
906        do
907                do
908                        FReadLine fileref, buffer                       //skip the "blank" lines that have one character
909                while(strlen(buffer) == 1)             
910
911                if (strlen(buffer) == 0)
912                        break
913                endif
914               
915                sscanf buffer,"%x",dataval
916               
917                //
918                //Constant ATXY = 0
919                //Constant ATXYM = 2
920                //Constant ATMIR = 1
921                //Constant ATMAR = 3
922                //
923//              type = (dataval & ~(2^32 - 2^30 -1))/2^30
924
925                // two most sig bits (31-30)
926                type = (dataval & 0xC0000000)/1073741824                //right shift by 2^30
927               
928                if(verbose > 0)
929                        verbose -= 1
930                endif
931//             
932                switch(type)
933                        case ATXY:
934                                if(verbose)             
935                                        printf "XY : "         
936                                endif
937//                              xval = ~(dataval & ~(2^32 - 2^8)) & 127
938//                              yval = ((dataval & ~(2^32 - 2^16 ))/2^8) & 127
939//                              time_lsw = (dataval & ~(2^32 - 2^29))/2^16
940
941                                xval = xMax - (dataval & 255)                                           //last 8 bits (7-0)
942                                yval = (dataval & 65280)/256                                            //bits 15-8, right shift by 2^8
943                                time_lsw = (dataval & 536805376)/65536                  //13 bits, 28-16, right shift by 2^16
944
945                                timeval = trunc( nRoll*roll_time + (time_msw * (8192)) + time_lsw )             //left shift msw by 2^13, then add in lsw, as an integer
946                                if (timeval > t_longest)
947                                        t_longest = timeval
948                                endif
949                                xLoc[ii] = xval
950                                yLoc[ii] = yval
951                                timePt[ii] = timeval
952
953                                if(verbose)             
954//                                      printf "%u : %u : %u : %u\r",dataval,time_lsw,time_msw,timeval
955                                        printf "d=%u : t=%u : msw=%u : lsw=%u : %u : %u \r",dataval,timeval,time_msw,time_lsw,xval,yval
956                                endif                           
957
958//                              b = FindBin(timeval,nslices)
959//                              slicedData[xval][yval][b] += 1
960
961                                ii+=1
962                               
963//                              verbose = 0
964                                break
965                        case ATXYM:
966                                if(verbose)
967                                        printf "XYM : "
968                                endif
969//                              xval = ~(dataval & ~(2^32 - 2^8)) & 127
970//                              yval = ((dataval & ~(2^32 - 2^16 ))/2^8) & 127
971//                              time_lsw =  (dataval & ~(2^32 - 2^29 ))/2^16
972
973                                xval = xMax - (dataval & 255)                                           //last 8 bits (7-0)
974                                yval = (dataval & 65280)/256                                            //bits 15-8, right shift by 2^8
975
976                                time_lsw = (dataval & 536805376)/65536                  //13 bits, 28-16, right shift by 2^16
977
978                                if(verbose)
979//                                      printf "%u : %u : %u : %u\r",dataval,time_lsw,time_msw,timeval
980                                        printf "%u : %u : %u : %u\r",dataval,timeval,xval,yval
981                                endif
982                               
983                                xLoc[ii] = xval
984                                yLoc[ii] = yval
985                               
986                                // don't fill in the time yet, or increment the index ii
987                                // the next event MUST be ATMIR with the MSW time bits
988                                //
989//                              verbose = 0
990                                break
991                        case ATMIR:
992                                if(verbose)
993                                        printf "MIR : "
994                                endif
995//                              time_msw =  (dataval & ~(2^32 - 2^29 ))/2^16
996                                time_msw =  (dataval & 536805376)/65536                 //13 bits, 28-16, right shift by 2^16
997                                timeval = trunc( nRoll*roll_time + (time_msw * (8192)) + time_lsw )
998                                if (timeval > t_longest)
999                                        t_longest = timeval
1000                                endif
1001                                if(verbose)
1002//                                      printf "%u : %u : %u : %u\r",dataval,time_lsw,time_msw,timeval
1003                                        printf "d=%u : t=%u : msw=%u : lsw=%u : tlong=%u\r",dataval,timeval,time_msw,time_lsw,t_longest
1004                                endif
1005                               
1006                                // the XY position was in the previous event ATXYM
1007                                timePt[ii] = timeval
1008                               
1009                                ii+=1
1010                               
1011//                              b = FindBin(timeval,nslices)
1012//                              slicedData[xval][yval][b] += 1
1013
1014//                              verbose = 0
1015                                break
1016                        case ATMAR:
1017                                if(verbose3)
1018//                                      verbose = 15
1019                                        verbose = 2
1020                                        printf "MAR : "
1021                                endif
1022                               
1023                                // do something with the rollover event?
1024                               
1025                                // check bit 29
1026                                rollBit = (dataval & 0x20000000)/536870912              //bit 29 only , shift by 2^29
1027                                nRoll += 1
1028                               
1029                                if(verbose3)
1030                                        printf "%u : %u : %u \r",dataval,rollBit,nRoll
1031                                endif
1032                               
1033                                break
1034                endswitch
1035                               
1036        while(1)
1037       
1038       
1039        Close fileref
1040       
1041        toc()
1042       
1043        SetDataFolder root:
1044       
1045        return(0)
1046       
1047End
1048
1049///
1050
1051Proc BinEventBarGraph()
1052        PauseUpdate; Silent 1           // building window...
1053        String fldrSav0= GetDataFolder(1)
1054        SetDataFolder root:Packages:NIST:Event:
1055        Display /W=(110,705,610,1132)/K=1 binCount vs binEndTime
1056        SetDataFolder fldrSav0
1057        ModifyGraph mode=5
1058        ModifyGraph marker=19
1059        ModifyGraph lSize=2
1060        ModifyGraph rgb=(0,0,0)
1061        ModifyGraph msize=2
1062        ModifyGraph hbFill=2
1063        ModifyGraph gaps=0
1064        ModifyGraph usePlusRGB=1
1065        ModifyGraph toMode=1
1066        ModifyGraph useBarStrokeRGB=1
1067//      ModifyGraph log=1
1068        ModifyGraph standoff=0
1069//      SetAxis left 0.1,4189
1070//      SetAxis bottom 0.0001,180.84853
1071End
1072
1073Proc ShowBinTable() : Table
1074        PauseUpdate; Silent 1           // building window...
1075        String fldrSav0= GetDataFolder(1)
1076        SetDataFolder root:Packages:NIST:Event:
1077        Edit/W=(498,699,1003,955) /K=1 binCount,binEndTime
1078        ModifyTable format(Point)=1,sigDigits(binEndTime)=16,width(binEndTime)=218
1079        SetDataFolder fldrSav0
1080EndMacro
1081
1082
1083// only show the first 1500 data points
1084//
1085Proc ShowRescaledTimeGraph() : Graph
1086        PauseUpdate; Silent 1           // building window...
1087        String fldrSav0= GetDataFolder(1)
1088        SetDataFolder root:Packages:NIST:Event:
1089        Display /W=(25,44,486,356)/K=1 rescaledTime
1090        SetDataFolder fldrSav0
1091        ModifyGraph mode=4
1092        ModifyGraph marker=19
1093        ModifyGraph rgb(rescaledTime)=(0,0,0)
1094        ModifyGraph msize=2
1095        SetAxis/A=2 left                        //only autoscale the visible data (based on the bottom limits)
1096        SetAxis bottom 0,1500
1097        ErrorBars rescaledTime OFF
1098        ShowInfo
1099EndMacro
1100
1101
1102
1103Proc ExportSlicesAsVAX(firstNum,prefix)
1104        Variable firstNum=1
1105        String prefix="SAMPL"
1106
1107        SaveSlicesAsVAX(firstNum,prefix[0,4])           //make sure that the prefix is 5 chars
1108End
1109
1110//////// procedures to be able to export the slices as RAW VAX files.
1111
1112// 1- load the raw data file to use the header (it must already be in RAW)
1113// 1.5- copy the raw data to the temp folder (STO)
1114// 1.7- ask for the prefix and starting run number (these are passed in)
1115// 2- copy the slice of data to the temp folder (STO)
1116// 3- touch up the time/counts in the slice header values in STO
1117// 4- write out the VAX file
1118// 5- repeat (2-4) for the number of slices
1119//
1120//
1121Function SaveSlicesAsVAX(firstNum,prefix)
1122        Variable firstNum
1123        String prefix
1124
1125        DoAlert 1,"Is the full data file loaded as a RAW data file? If not, load it and start over..."
1126        if(V_flag == 2)
1127                return (0)
1128        endif
1129       
1130// copy the contents of RAW to STO so I can work from there
1131        CopyWorkContents("RAW","STO")
1132
1133        // now declare all of the waves, now that they are sure to be there
1134
1135        WAVE slicedData=root:Packages:NIST:Event:slicedData
1136        Make/O/D/N=(128,128) curSlice
1137       
1138        NVAR nslices = root:Packages:NIST:gEvent_nslices
1139        WAVE binEndTime = root:Packages:NIST:Event:binEndTime
1140
1141        Wave rw=root:Packages:NIST:STO:realsRead
1142        Wave iw=root:Packages:NIST:STO:integersRead
1143        Wave/T tw=root:Packages:NIST:STO:textRead
1144        Wave data=root:Packages:NIST:STO:data
1145        Wave linear_data=root:Packages:NIST:STO:linear_data
1146       
1147       
1148        Wave rw_raw=root:Packages:NIST:RAW:realsRead
1149        Wave iw_raw=root:Packages:NIST:RAW:integersRead
1150        Wave/T tw_raw=root:Packages:NIST:RAW:textRead
1151
1152// for generating the alphanumeric
1153        String timeStr= secs2date(datetime,-1)
1154        String monthStr=StringFromList(1, timeStr  ,"/")
1155        String numStr="",labelStr
1156
1157        Variable ii,err,binFraction
1158       
1159        for(ii=0;ii<nslices;ii+=1)
1160
1161                //get the current slice and put it in the STO folder
1162                curSlice = slicedData[p][q][ii]
1163                data = curSlice
1164                linear_data = curSlice
1165               
1166                // touch up the header as needed
1167                // count time = iw[2]
1168                // monCt = rw[0]
1169                // detCt = rw[2]
1170                //tw[0] must now be the file name
1171                //
1172                // count time = fraction of total binning * total count time
1173                binFraction = (binEndTime[ii+1]-binEndTime[ii])/(binEndTime[nslices]-binEndTime[0])
1174               
1175                iw[2] = trunc(binFraction*iw_raw[2])
1176                rw[0] = trunc(binFraction*rw_raw[0])
1177                rw[2] = sum(curSlice,-inf,inf)          //total counts in slice
1178       
1179                if(firstNum<10)
1180                        numStr = "00"+num2str(firstNum)
1181                else
1182                        if(firstNum<100)
1183                                numStr = "0"+num2str(firstNum)
1184                        else
1185                                numStr = num2str(firstNum)
1186                        Endif
1187                Endif   
1188                tw[0] = prefix+numstr+".SA2_EVE_"+(num2char(str2num(monthStr)+64))+numStr
1189                labelStr = tw_raw[6]
1190               
1191                labelStr = PadString(labelStr,60,0x20)  //60 fortran-style spaces
1192                tw[6] = labelStr[0,59]
1193               
1194                //write out the file - this uses the tw[0] and home path
1195                Write_VAXRaw_Data("STO","",0)
1196
1197                //increment the run number, alpha
1198                firstNum += 1   
1199        endfor
1200
1201        return(0)
1202End
1203
1204
1205
1206
1207
1208/////////////
1209//The histogramming
1210//
1211// 6 AUG 2012
1212//
1213// from Igor Exchange, RGerkin
1214//  http://www.igorexchange.com/node/1373
1215// -- see the related thread on the mailing list
1216//
1217
1218//
1219// Now see if this can be succesfully applied to the timeslicing data sets
1220// -- talk to Jeff about what he's gotten implemented, and what's still missing
1221// - both in timeslicing, and in TISANE
1222// - un-scale the wave? or make it work as 128x128
1223
1224Function Setup_JointHistogram()
1225
1226//      tic()
1227
1228        make/D /o/n=1000000 data1=gnoise(1), data2=gnoise(1)
1229        make/D /o/n=(25,25) myHist
1230        setscale x,-3,3,myHist
1231        setscale y,-3,3,myHist
1232        IndexForHistogram(data1,data2,myhist)
1233        Wave index=SavedIndex
1234        JointHistogram(data1,data2,myHist,index)
1235        NewImage myHist
1236       
1237//      toc()
1238       
1239End
1240
1241
1242Function JointHistogram(w0,w1,hist,index)
1243        wave w0,w1,hist,index
1244 
1245        variable bins0=dimsize(hist,0)
1246        variable bins1=dimsize(hist,1)
1247        variable n=numpnts(w0)
1248        variable left0=dimoffset(hist,0)
1249        variable left1=dimoffset(hist,1)
1250        variable right0=left0+bins0*dimdelta(hist,0)
1251        variable right1=left1+bins1*dimdelta(hist,1)
1252       
1253        // Compute the histogram and redimension it. 
1254        histogram /b={0,1,bins0*bins1} index,hist
1255        redimension/D /n=(bins0,bins1) hist // Redimension to 2D. 
1256        setscale x,left0,right0,hist // Fix the histogram scaling in the x-dimension. 
1257        setscale y,left1,right1,hist // Fix the histogram scaling in the y-dimension. 
1258End
1259
1260
1261// need a way of visualizing the bin spacing / number of bins vs the full time of the data collection
1262// then set the range of the source to send to the joint histogram operation
1263// to assign to arrays (or a 3D wave)
1264//
1265// -- see my model with the "layered" form factor - or whatever I called it. That shows different
1266// binning and visualizing as bar graphs.
1267//
1268// -- just need to send x2pnt or findLevel, or something similar to define the POINT
1269// values
1270//
1271// can also speed this up since the index only needs to be done once, so the
1272// histogram operation can be done separately, as the bins require
1273//
1274//
1275Function JointHistogramWithRange(w0,w1,hist,index,pt1,pt2)
1276        wave w0,w1,hist,index
1277        Variable pt1,pt2
1278 
1279        variable bins0=dimsize(hist,0)
1280        variable bins1=dimsize(hist,1)
1281        variable n=numpnts(w0)
1282        variable left0=dimoffset(hist,0)
1283        variable left1=dimoffset(hist,1)
1284        variable right0=left0+bins0*dimdelta(hist,0)
1285        variable right1=left1+bins1*dimdelta(hist,1)
1286
1287        // Compute the histogram and redimension it. 
1288        histogram /b={0,1,bins0*bins1}/R=[pt1,pt2] index,hist
1289        redimension/D /n=(bins0,bins1) hist // Redimension to 2D. 
1290        setscale x,left0,right0,hist // Fix the histogram scaling in the x-dimension. 
1291        setscale y,left1,right1,hist // Fix the histogram scaling in the y-dimension. 
1292End
1293
1294
1295// just does the indexing, creates wave SavedIndex in the current folder for the index
1296//
1297Function IndexForHistogram(w0,w1,hist)
1298        wave w0,w1,hist
1299 
1300        variable bins0=dimsize(hist,0)
1301        variable bins1=dimsize(hist,1)
1302        variable n=numpnts(w0)
1303        variable left0=dimoffset(hist,0)
1304        variable left1=dimoffset(hist,1)
1305        variable right0=left0+bins0*dimdelta(hist,0)
1306        variable right1=left1+bins1*dimdelta(hist,1)
1307 
1308        // Scale between 0 and the number of bins to create an index wave. 
1309        if(ThreadProcessorCount<4) // For older machines, matrixop is faster. 
1310                matrixop /free idx=round(bins0*(w0-left0)/(right0-left0))+bins0*round(bins1*(w1-left1)/(right1-left1))
1311        else // For newer machines with many cores, multithreading with make is faster. 
1312                make/free/n=(n) idx
1313                multithread idx=round(bins0*(w0-left0)/(right0-left0))+bins0*round(bins1*(w1-left1)/(right1-left1))
1314        endif
1315 
1316        KillWaves/Z SavedIndex
1317        MoveWave idx,SavedIndex
1318       
1319//      // Compute the histogram and redimension it. 
1320//      histogram /b={0,1,bins0*bins1} idx,hist
1321//      redimension /n=(bins0,bins1) hist // Redimension to 2D. 
1322//      setscale x,left0,right0,hist // Fix the histogram scaling in the x-dimension. 
1323//      setscale y,left1,right1,hist // Fix the histogram scaling in the y-dimension. 
1324End
1325
1326
1327
1328
1329///////
1330//// @ IgorExchange
1331////TicToc
1332////Posted April 16th, 2009 by bgallarda
1333////    ¥       in Programming 6.10.x
1334//     
1335//function tic()
1336//      variable/G tictoc = startMSTimer
1337//end
1338//
1339//function toc()
1340//      NVAR/Z tictoc
1341//      variable ttTime = stopMSTimer(tictoc)
1342//      printf "%g seconds\r", (ttTime/1e6)
1343//      killvariables/Z tictoc
1344//end
1345//
1346//
1347//Function testTicToc()
1348//
1349//      tic()
1350//      variable i
1351//      For(i=0;i<10000;i+=1)
1352//              make/O/N=512 temp = gnoise(2)
1353//              FFT temp
1354//      Endfor
1355//      killwaves/z temp
1356//      toc()
1357//End
1358//
1359////////////////
Note: See TracBrowser for help on using the repository browser.