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

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

minor changes to the event mode reader to allow for periods of oscillation longer than 6.7 seconds. Now T0 is explicitly identified and nRollover is reset if T0 is found. Appears to work, until something breaks it...

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