source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/VSANS/V_EventMode_Utils.ipf @ 1247

Last change on this file since 1247 was 1247, checked in by srkline, 2 years ago

more changes to panel scaling so that they are viewed properly on a small-screen laptop

File size: 47.7 KB
Line 
1#pragma TextEncoding = "MacRoman"
2#pragma rtGlobals=3             // Use modern global access method and strict wave access.
3#pragma IgorVersion = 7.00
4
5
6//
7// There are functions in this file to generate "fake" event data for testing
8//
9
10
11//
12// for the event mode data with the proposed 64 bit structure, I may be able to use Igor for everything.
13//
14// Skipping the appropriate bits of the header (after I read them in) may be possible with
15// either LoadWave (treating the entire wave as 64 bit, unsigned), loading chunks from clipboard?
16// -- see in LoadWave, the suggestions for "Loading Large Waves"
17//
18// or using FBinRead, again, filling a wave, or a chunk of the data, as needed
19//
20// Then - since the data has sequential timing, not dependent on rollovers, I can
21// chunk the data for parallel processing, and piece it back together
22// after all of the decoding is done.
23//
24//
25// I don't know if it's possible to use a STRUCT  definition for each 64 bit word so that I could address
26// the bytes directly - since that may not work properly in Igor, and I'm not sure how to address the 6 byte section
27// -possibly with a uchar(6) definition?
28//
29//
30//      (from WM help) You can define an array of structures as a field in a structure:
31//              Structure mystruct
32//                      STRUCT Point pt[100]                    // Allowed as a sub-structure
33//              EndStructure
34//
35// -- which may be of use to read "blocks" of datq from a file using FBinRead
36//
37// -- right now, I'm having issues with being able to "cast" or convert uint64 values to STRUCT
38// (I don't know how to read from the struct if I can't fill it??)
39//
40// TODO:
41//
42// (5/2017)
43// The basic bits of reading work, but will need to be customized to be able to accomodate file names in/out
44// and especially the number of disabled tubes (although as long as I have the offset, it shouldn't be that
45// big of an issue.
46//
47// -- don't see the struct idea working out. only in real c-code if needed
48//
49// -- need to add detector binning to the decoding, to place the counts within the correct panels
50// -- not sure how this will work with JointHistogram Operation
51// (split to separate "streams" of values for each detector panel?
52//
53//
54// -- can I efficiently use "sort" (on the tube index) to block the data into groups that can be split
55//  into 4 sets of waves
56//  that can then be binned per panel, using the usual Joint histogram procedures? Works only if the
57// tube indexing is orderly. if it's a mess, Ill need to try something else (indexed sort?) (replace?)
58// (manually? ugh.)
59//
60
61//
62////
63//Structure eventWord
64//      uchar eventTime[6]
65//      uchar location
66//      uchar tube
67//endStructure
68
69
70
71//
72//
73Function V_testBitShift()
74
75//      // /l=64 bit, /U=unsigned
76//      Make/L/U/N=100 eventWave
77//      eventWave = 0
78       
79        // for each 64-bit value:
80        // byte 1: tube index [0,191]
81        // byte 2: pixel value [0,127]
82        // bytes 3-8 (= 6 bytes): time stamp in resolution unit
83       
84        int64 i64_num,b1,b2,b3,b4,b5,b6,b7,b8
85        int64 i64_ticks,i64_start
86       
87        b1=255
88        b3=255
89        b5=255
90        b7=255
91        b2=0
92        b4=0
93        b6=0
94        b8=0
95       
96        b7 = b7 << 8
97        b6 = b6 << 16
98        b5 = b5 << 24
99        b4 = b4 << 32
100        b3 = b3 << 40
101        b2 = b2 << 48
102        b1 = b1 << 56
103       
104        i64_num = b1+b2+b3+b4+b5+b6+b7+b8
105        printf "%64b\r",i64_num
106       
107        return(0)
108End
109
110Function V_MakeFakeEvents()
111
112//      // /l=64 bit, /U=unsigned
113        Make/O/L/U/N=10 smallEventWave
114        smallEventWave = 0
115       
116        // for each 64-bit value:
117        // byte 1: tube index [0,191]
118        // byte 2: pixel value [0,127]
119        // bytes 3-8 (= 6 bytes): time stamp in resolution unit
120       
121        uint64 i64_num,b1,b2,b3,b4,b5,b6,b7,b8
122        uint64 i64_ticks,i64_start
123       
124//      b1 = 47
125//      b2 = 123
126//      i64_ticks = 123456789
127        b1 = 41
128        b2 = 66
129        i64_ticks = 15
130
131
132//      b2 = b2 << 48
133//      b1 = b1 << 56
134//     
135//      i64_num = b1+b2+i64_ticks
136
137        // don't shift b1
138        b2 = b2 << 8
139        i64_ticks = i64_ticks << 16
140
141        i64_num = b1+b2+i64_ticks
142
143        printf "%64b\r",i64_num
144        print i64_num
145       
146        smallEventWave[0] = i64_num
147       
148        return(0)
149End
150
151Function V_decodeFakeEvent()
152
153        WAVE w = smallEventWave
154        uint64 val,b1,b2,btime
155        val = w[0]
156       
157//      printf "%64b\r",w[0]            //wrong (drops the last Å 9 bits)
158        printf "%64b\r",val                     //correct, assign value to 64bit variable
159//      print w[0]                              //wrong
160        print val                               // correct
161       
162//      b1 = (val >> 56 ) & 0xFF                        // = 255, last byte, after shifting
163//      b2 = (val >> 48 ) & 0xFF       
164//      btime = val & 0xFFFFFFFFFFFF    // = really big number, last 6 bytes
165
166
167        b1 = val & 0xFF
168        b2 = (val >> 8) & 0xFF
169        btime = (val >> 16)
170
171       
172        print b1
173        print b2
174        print btime
175
176
177//      //test as struct
178//      Print "as STRUCT"
179//     
180//      STRUCT eventWord s
181//     
182//      s = w[0]
183//     
184//      print s.tube
185//      print s.location
186//      print s.eventTime
187       
188
189               
190        return(0)
191End
192
193//
194// tested up to num=1e8 successfully
195//
196Function V_MakeFakeEventWave(num)
197        Variable num
198       
199        Variable ii
200
201
202//      num = 1e3
203       
204//      // /l=64 bit, /U=unsigned
205        Make/O/L/U/N=(num) eventWave
206        eventWave = 0
207       
208        // for each 64-bit value:
209        // byte 1: tube index [0,191]
210        // byte 2: pixel value [0,127]
211        // bytes 3-8 (= 6 bytes): time stamp in resolution unit
212       
213        uint64 i64_num,b1,b2
214        uint64 i64_ticks,i64_start
215       
216        i64_start = ticks
217        for(ii=0;ii<num;ii+=1)
218//              sleep/T/C=-1 1                  // 6 ticks, approx 0.1 s (without the delay, the loop is too fast)
219                b1 = trunc(abs(enoise(192)))            //since truncated, need 192 as highest random to give 191 after trunc
220                b2 = trunc(abs(enoise(128)))            // same here, to get results [0,127]
221               
222//              i64_ticks = ticks-i64_start
223                i64_ticks = ii+1
224               
225//              b2 = b2 << 48
226//              b1 = b1 << 56
227
228                // don't shift b1
229                b2 = b2 << 8
230                i64_ticks = i64_ticks << 16
231       
232                i64_num = b1+b2+i64_ticks
233       
234                eventWave[ii] = i64_num
235        endfor
236
237
238        return(0)
239End
240
241
242//
243// TODO:
244// -- can this be multithreaded (eliminating the loop)?
245//
246// MultiThread tube = (w[p]) & 0xFF     
247// MultiThread location = (w[p] >> 8 ) & 0xFF   
248// MultiThread eventTime = (w[p] >> 16)
249//
250// !!!!- yes - for a 35 MB file:
251// for loop = 4.3 s
252// MultiThread = 0.35 s
253//
254// !!! can I use the bit operations in MatrixOp? 1D waves are valid
255//  to use with MatrixOp. Would it be better than multiThread?
256//
257//
258Function V_decodeFakeEventWave(w)
259        Wave w
260
261v_tic()
262//      WAVE w = eventWave
263        uint64 val,b1,b2,btime
264        val = w[0]
265       
266//      printf "%64b\r",w[0]            //wrong (drops the last Å 9 bits)
267//      printf "%64b\r",val                     //correct, assign value to 64bit variable
268//      print w[0]                              //wrong
269//      print val                               // correct
270       
271        Variable num,ii
272        num=numpnts(w)
273       
274        Make/O/L/U/N=(num) eventTime
275        Make/O/U/B/N=(num) tube,location                //8 bit unsigned
276
277 MultiThread tube = (w[p]) & 0xFF       
278 MultiThread location = (w[p] >> 8 ) & 0xFF     
279 MultiThread eventTime = (w[p] >> 16)
280       
281//      for(ii=0;ii<num;ii+=1)
282//              val = w[ii]
283//             
284////            b1 = (val >> 56 ) & 0xFF                        // = 255, last two bytes, after shifting
285////            b2 = (val >> 48 ) & 0xFF       
286////            btime = val & 0xFFFFFFFFFFFF    // = really big number, last 6 bytes
287//
288//              b1 = val & 0xFF
289//              b2 = (val >> 8) & 0xFF
290//              btime = (val >> 16)
291//
292//              tube[ii] = b1
293//              location[ii] = b2
294//              eventTime[ii] = btime
295//             
296//      endfor
297
298v_toc()
299               
300        return(0)
301End
302
303
304Function V_writeFakeEventFile(fname)
305        String fname
306
307        WAVE w = eventWave
308        Variable refnum
309       
310        String vsansStr="VSANS"
311        Variable revision = 11
312        Variable offset = 26            // no disabled tubes
313        Variable time1 = 2017
314        Variable time2 = 0525
315        Variable time3 = 1122
316        Variable time4 = 3344           // these 4 time pieces are supposed to be 8 bytes total
317        Variable time5 = 3344           // these 5 time pieces are supposed to be 10 bytes total
318        String detStr = "M"
319        Variable volt = 1500
320        Variable resol = 1e7
321       
322       
323        Open refnum as fname
324
325        FBinWrite refnum, vsansStr
326        FBinWrite/F=2/U refnum, revision
327        FBinWrite/F=2/U refnum, offset
328        FBinWrite/F=2/U refnum, time1
329        FBinWrite/F=2/U refnum, time2
330        FBinWrite/F=2/U refnum, time3
331        FBinWrite/F=2/U refnum, time4
332        FBinWrite/F=2/U refnum, time5
333        FBinWrite refnum, detStr
334        FBinWrite/F=2/U refnum, volt
335        FBinWrite/F=3/U refnum, resol
336
337        FGetPos refnum
338        Print "End of header = ",V_filePos
339        offset = V_filePos
340       
341        FSetPos refnum,7
342        FBinWrite/F=2/U refnum, offset                  //write the correct offset
343
344       
345        FSetPos refNum, offset
346       
347        FBinWrite refnum, w
348       
349        close refnum
350       
351        return(0)
352End
353
354//
355// use GBLoadWave to do the reading, then I can do the decoding
356//
357Function V_readFakeEventFile(fileName)
358        String filename
359       
360// this reads in uint64 data, to a unit64 wave, skipping 22 bytes       
361//      GBLoadWave/B/T={192,192}/W=1/S=22
362        Variable num,refnum
363       
364
365//  to read a VSANS event file:
366//
367// - get the file name
368//      - read the header (all of it, since I need parts of it) (maybe read as a struct? but I don't know the size!)
369// - move to EOF and close
370//
371// - Use GBLoadWave to read the 64-bit events in
372
373        String vsansStr=""
374        Variable revision
375        Variable offset         // no disabled tubes
376        Variable time1
377        Variable time2
378        Variable time3
379        Variable time4          // these 4 time pieces are supposed to be 8 bytes total
380        Variable time5          // these 5 time pieces are supposed to be 10 bytes total
381        String detStr=""
382        Variable volt
383        Variable resol
384
385        vsansStr = PadString(vsansStr,5,0x20)           //pad to 5 bytes
386        detStr = PadString(detStr,1,0x20)                               //pad to 1 byte
387
388        Open/R refnum as filename
389        filename = S_fileName
390
391v_tic()
392
393        FBinRead refnum, vsansStr
394        FBinRead/F=2/U refnum, revision
395        FBinRead/F=2/U refnum, offset
396        FBinRead/F=2/U refnum, time1
397        FBinRead/F=2/U refnum, time2
398        FBinRead/F=2/U refnum, time3
399        FBinRead/F=2/U refnum, time4
400        FBinRead/F=2/U refnum, time5
401        FBinRead refnum, detStr                 //NOTE - the example data file Phil sent skipped the detStr (no placeholder!)
402        FBinRead/F=2/U refnum, volt
403        FBinRead/F=3/U refnum, resol
404
405        FStatus refnum
406        FSetPos refnum, V_logEOF
407       
408        Close refnum
409       
410// number of data bytes
411        num = V_logEOF-offset
412        Print "Number of data values = ",num/8
413       
414        GBLoadWave/B/T={192,192}/W=1/S=(offset) filename                // intel, little-endian
415//      GBLoadWave/T={192,192}/W=1/S=(offset) filename                  // motorola, big-endian
416       
417        Duplicate/O $(StringFromList(0,S_waveNames)) V_Events
418        KillWaves/Z $(StringFromList(0,S_waveNames))
419v_toc()
420       
421        Print vsansStr
422        Print revision
423        Print offset
424        Print time1
425        Print time2
426        Print time3
427        Print time4
428        Print time5
429        Print detStr
430        print volt
431        print resol
432       
433        return(0)
434End
435
436//
437//
438//
439Function V_MakeFakeEventWave_TOF(delayTime,std)
440        Variable delayTime,std
441
442        Variable num,ii,jj,numRepeat
443
444
445        num = 1000
446        numRepeat = 1000
447       
448//      delayTime = 50          //microseconds
449//      std = 4                                 //std deviation, microseconds
450       
451//      // /l=64 bit, /U=unsigned
452        Make/O/L/U/N=(num*numRepeat) eventWave
453        eventWave = 0
454       
455        Make/O/D/N=(num) arrival
456       
457        // for each 64-bit value:
458        // byte 1: tube index [0,191]
459        // byte 2: pixel value [0,127]
460        // bytes 3-8 (= 6 bytes): time stamp in resolution unit
461       
462        uint64 i64_num,b1,b2,b3,b4,b5,b6,b7,b8
463        uint64 i64_ticks,i64_start
464       
465//      i64_start = ticks
466        i64_ticks = 0
467        for(jj=0;jj<numRepeat;jj+=1)
468                arrival = delayTime + gnoise(std)
469                sort arrival,arrival
470                arrival *= 1000         //milliseconds now
471       
472                for(ii=0;ii<num;ii+=1)
473        //              sleep/T/C=-1 1                  // 6 ticks, approx 0.1 s (without the delay, the loop is too fast)
474                        b1 = trunc(abs(enoise(192)))            //since truncated, need 192 as highest random to give 191 after trunc
475                        b2 = trunc(abs(enoise(128)))            // same here, to get results [0,127]
476                       
477                        i64_ticks = trunc(arrival[ii])
478                       
479//                      b2 = b2 << 48
480//                      b1 = b1 << 56
481
482                        // don't shift b1
483                        b2 = b2 << 8
484                        i64_ticks = i64_ticks << 16
485               
486                        i64_num = b1+b2+i64_ticks
487                        eventWave[jj*num+ii] = i64_num
488                endfor
489               
490        endfor
491
492        return(0)
493End
494
495
496// TODO:
497//
498// There may be memory issues with this
499//
500// -- do I want to do the time binning first?
501// -- does it really matter?
502//
503Function V_SortAndSplitFakeEvents()
504
505        Wave eventTime = root:EventTime
506        Wave location = root:location
507        Wave tube = root:tube
508       
509        Sort tube,tube,eventTime,location
510
511        Variable b1,e1,b2,e2,b3,e3,b4,e4       
512        FindValue/S=0/I=48 tube
513        b1 = 0
514        e1 = V_Value - 1
515        b2 = V_Value
516        FindValue/S=(b2)/I=96 tube
517        e2 = V_Value - 1
518        b3 = V_Value
519        FindValue/S=(b3)/I=144 tube
520        e3 = V_Value - 1
521        b4 = V_Value
522        e4 = numpnts(tube)-1
523       
524        Print b1,e1
525        Print b2,e2
526        Print b3,e3
527        Print b4,e4
528       
529//      tube and location become x and y, and can be byte data
530// eventTime still needs to be 64 bit - when do I convert it to FP?
531        Make/O/B/U/N=(e1-b1+1) tube1,location1
532        Make/O/L/U/N=(e1-b1+1) eventTime1
533
534        Make/O/B/U/N=(e2-b2+1) tube2,location2
535        Make/O/L/U/N=(e2-b2+1) eventTime2
536       
537        Make/O/B/U/N=(e3-b3+1) tube3,location3
538        Make/O/L/U/N=(e3-b3+1) eventTime3
539       
540        Make/O/B/U/N=(e4-b4+1) tube4,location4
541        Make/O/L/U/N=(e4-b4+1) eventTime4
542       
543       
544        tube1 = tube[p+b1]
545        tube2 = tube[p+b2]
546        tube3 = tube[p+b3]
547        tube4 = tube[p+b4]
548       
549        location1 = location[p+b1]
550        location2 = location[p+b2]
551        location3 = location[p+b3]
552        location4 = location[p+b4]
553       
554        eventTime1 = eventTime[p+b1]
555        eventTime2 = eventTime[p+b2]
556        eventTime3 = eventTime[p+b3]
557        eventTime4 = eventTime[p+b4]
558       
559       
560        KillWaves/Z eventTime,location,tube
561       
562        return(0)
563End
564
565
566
567// TODO:
568//
569// There may be memory issues with this
570//
571// -- do I want to do the time binning first?
572// -- does it really matter?
573//
574Function V_SortAndSplitEvents()
575
576
577        SetDataFolder root:Packages:NIST:VSANS:Event:
578       
579        Wave eventTime = EventTime
580        Wave location = location
581        Wave tube = tube
582
583        Variable t1=ticks
584 Print "sort started"   
585        Sort tube,tube,eventTime,location
586print "sort done ",(ticks-t1)/60
587
588        Variable b1,e1,b2,e2,b3,e3,b4,e4       
589        FindValue/S=0/I=48 tube
590        b1 = 0
591        e1 = V_Value - 1
592        b2 = V_Value
593        FindValue/S=(b2)/I=96 tube
594        e2 = V_Value - 1
595        b3 = V_Value
596        FindValue/S=(b3)/I=144 tube
597        e3 = V_Value - 1
598        b4 = V_Value
599        e4 = numpnts(tube)-1
600       
601        Print b1,e1
602        Print b2,e2
603        Print b3,e3
604        Print b4,e4
605       
606//      tube and location become x and y, and can be byte data
607// eventTime still needs to be 64 bit - when do I convert it to FP?
608        Make/O/B/U/N=(e1-b1+1) tube1,location1
609        Make/O/L/U/N=(e1-b1+1) eventTime1
610
611        Make/O/B/U/N=(e2-b2+1) tube2,location2
612        Make/O/L/U/N=(e2-b2+1) eventTime2
613       
614        Make/O/B/U/N=(e3-b3+1) tube3,location3
615        Make/O/L/U/N=(e3-b3+1) eventTime3
616       
617        Make/O/B/U/N=(e4-b4+1) tube4,location4
618        Make/O/L/U/N=(e4-b4+1) eventTime4
619       
620       
621        tube1 = tube[p+b1]
622        tube2 = tube[p+b2]
623        tube3 = tube[p+b3]
624        tube4 = tube[p+b4]
625       
626        location1 = location[p+b1]
627        location2 = location[p+b2]
628        location3 = location[p+b3]
629        location4 = location[p+b4]
630       
631        eventTime1 = eventTime[p+b1]
632        eventTime2 = eventTime[p+b2]
633        eventTime3 = eventTime[p+b3]
634        eventTime4 = eventTime[p+b4]
635       
636       
637        KillWaves/Z eventTime,location,tube
638       
639        return(0)
640End
641
642
643//
644// switch the "active" panel to the selected group (1-4) (5 concatenates them all together)
645//
646
647//
648// copy the set of tubes over to the "active" set that is to be histogrammed
649// and redimension them to be sure that they are double precision
650//
651Function V_SwitchTubeGroup(tubeGroup)
652        Variable tubeGroup
653       
654        SetDataFolder root:Packages:NIST:VSANS:Event:
655       
656        if(tubeGroup <= 4)
657                Wave tube = $("tube"+num2Str(tubeGroup))
658                Wave location = $("location"+num2Str(tubeGroup))
659                Wave eventTime = $("eventTime"+num2Str(tubeGroup))
660               
661                Wave/Z xloc,yLoc,timePt
662               
663                KillWaves/Z timePt,xLoc,yLoc
664                Duplicate/O eventTime timePt
665
666// TODO:
667// -- for processing, initially treat all of the tubes along x, and 128 pixels along y
668//   panels can be transposed later as needed to get the orientation correct
669
670
671//              if(tubeGroup == 1 || tubeGroup == 4)   
672                // L/R panels, they have tubes along x 
673                        Duplicate/O tube xLoc
674                        Duplicate/O location yLoc
675//              else
676//              // T/B panels, tubes are along y
677//                      Duplicate/O tube yLoc
678//                      Duplicate/O location xLoc               
679//              endif
680               
681                Redimension/D xLoc,yLoc,timePt 
682               
683        endif
684       
685        if(tubeGroup == 5)
686                Wave xloc,yLoc,timePt
687               
688                KillWaves/Z timePt,xLoc,yLoc
689               
690                String str = ""
691                str = "tube1;tube2;tube3;tube4;"
692                Concatenate/O/NP str,xloc
693                str = "location1;location2;location3;location4;"
694                Concatenate/O/NP str,yloc
695                str = "eventTime1;eventTime2;eventTime3;eventTime4;"
696                Concatenate/O/NP str,timePt
697               
698                Redimension/D xLoc,yLoc,timePt 
699        endif
700       
701       
702        return(0)
703End
704
705Proc V_SwitchGroupAndCleanup(num)
706        Variable num
707       
708        V_SwitchTubeGroup(num)
709        SetDataFolder root:Packages:NIST:VSANS:Event:
710        Duplicate/O timePt rescaledTime
711        KillWaves/Z OscSortIndex
712        print WaveMax(rescaledTime)
713        root:Packages:NIST:VSANS:Event:gEvent_t_longest = waveMax(rescaledTime)
714       
715        SetDataFolder root:
716
717end
718
719Function V_count(num)
720        Variable num
721       
722        SetDataFolder root:Packages:NIST:VSANS:Event:
723
724        Wave xloc = xloc
725        wave yloc = yloc
726        Variable ii,npt,total=0
727        npt = numpnts(xloc)
728        for(ii=0;ii<npt;ii+=1)
729                if(xloc[ii] == num)
730                        total += 1
731                endif
732                if(yloc[ii] == num)
733                        total += 1
734                endif
735        endfor
736       
737        Print total
738       
739        SetDataFolder root:
740        return(0)
741end
742
743
744
745// Based on the numbering 0-191:
746// group 1 = R (0,47)                   MatrixOp out = ReverseRows(in)
747// group 2 = T (48,95)          output = slices_T[q][p][r]
748// group 3 = B (96,143)                 output = slices_B[XBINS-q-1][YBINS-p-1][r]              (reverses rows and columns)
749// group 4 = L (144,191)        MatrixOp out = ReverseCols(in)
750//
751// the transformation flips the panel to the view as if the detector was viewed from the sample position
752// (this is the standard view for SANS and VSANS)
753//
754// Takes the data that was binned, and separates it into the 4 detector panels
755// Waves are 3D waves x-y-time
756//
757// MatrixOp may not be necessary for the R/L transformations, but indexing or MatrixOp are both really fast.
758//
759//
760Function V_SplitBinnedToPanels()
761
762        SetDataFolder root:Packages:NIST:VSANS:Event:   
763        Wave slicedData = slicedData            //this is 3D
764       
765        Variable nSlices = DimSize(slicedData,2)
766       
767        Make/O/D/N=(XBINS,YBINS,nSlices) slices_R, slices_L, slices_T, slices_B, output
768       
769        slices_R = slicedData[p][q][r]
770        slices_T = slicedData[p+48][q][r]
771        slices_B = slicedData[p+96][q][r]
772        slices_L = slicedData[p+144][q][r]
773       
774        MatrixOp/O output = ReverseRows(slices_R)
775        slices_R = output
776       
777        MatrixOp/O output = ReverseCols(slices_L)
778        slices_L = output
779
780               
781        Redimension/N=(YBINS,XBINS,nSlices) output
782        output = slices_T[q][p][r]
783        KillWaves/Z slices_T
784        Duplicate/O output slices_T
785       
786        output = slices_B[XBINS-q-1][YBINS-p-1][r]
787        KillWaves/Z slices_B
788        Duplicate/O output slices_B
789       
790        KillWaves/Z output
791        SetDataFolder root:
792
793        return(0)
794End
795
796
797// simple panel to display the 4 detector panels after the data has been binned and sliced
798//
799// TODO:
800// -- label panels, axes
801// -- add a way to display different slices (this can still be done on the main panel, all at once)
802// -- any other manipulations?
803//
804
805Proc VSANS_EventPanels()
806        PauseUpdate; Silent 1           // building window...
807        NewPanel /W=(720,45,1530,570)/N=VSANS_EventPanels/K=1
808        DoWindow/C VSANS_EventPanels
809        ModifyPanel fixedSize=1,noEdit =1
810
811//      Display/W=(745,45,945,425)/HOST=#
812        Display/W=(10,45,210,425)/HOST=#
813        AppendImage/T/G=1 :Packages:NIST:VSANS:Event:slices_L           //  /G=1 flag prevents interpretation as RGB so 3, 4 slices display correctly
814        ModifyImage slices_L ctab= {*,*,ColdWarm,0}
815        ModifyImage slices_L ctabAutoscale=3
816        ModifyGraph margin(left)=14,margin(bottom)=14,margin(top)=14,margin(right)=14
817        ModifyGraph mirror=2
818        ModifyGraph nticks=4
819        ModifyGraph minor=1
820        ModifyGraph fSize=9
821        ModifyGraph standoff=0
822        ModifyGraph tkLblRot(left)=90
823        ModifyGraph btLen=3
824        ModifyGraph tlOffset=-2
825        RenameWindow #,Event_slice_L
826        SetActiveSubwindow ##
827
828//      Display/W=(1300,45,1500,425)/HOST=#
829        Display/W=(565,45,765,425)/HOST=#
830        AppendImage/T/G=1 :Packages:NIST:VSANS:Event:slices_R           //  /G=1 flag prevents interpretation as RGB so 3, 4 slices display correctly
831        ModifyImage slices_R ctab= {*,*,ColdWarm,0}
832        ModifyImage slices_R ctabAutoscale=3
833        ModifyGraph margin(left)=14,margin(bottom)=14,margin(top)=14,margin(right)=14
834        ModifyGraph mirror=2
835        ModifyGraph nticks=4
836        ModifyGraph minor=1
837        ModifyGraph fSize=9
838        ModifyGraph standoff=0
839        ModifyGraph tkLblRot(left)=90
840        ModifyGraph btLen=3
841        ModifyGraph tlOffset=-2
842        RenameWindow #,Event_slice_R
843        SetActiveSubwindow ##
844
845//      Display/W=(945,45,1300,235)/HOST=#
846        Display/W=(210,45,565,235)/HOST=#
847        AppendImage/T/G=1 :Packages:NIST:VSANS:Event:slices_T           //  /G=1 flag prevents interpretation as RGB so 3, 4 slices display correctly
848        ModifyImage slices_T ctab= {*,*,ColdWarm,0}
849        ModifyImage slices_T ctabAutoscale=3
850        ModifyGraph margin(left)=14,margin(bottom)=14,margin(top)=14,margin(right)=14
851        ModifyGraph mirror=2
852        ModifyGraph nticks=4
853        ModifyGraph minor=1
854        ModifyGraph fSize=9
855        ModifyGraph standoff=0
856        ModifyGraph tkLblRot(left)=90
857        ModifyGraph btLen=3
858        ModifyGraph tlOffset=-2
859        RenameWindow #,Event_slice_T
860        SetActiveSubwindow ##
861
862//      Display/W=(945,235,1300,425)/HOST=#
863        Display/W=(210,235,565,425)/HOST=#
864        AppendImage/T/G=1 :Packages:NIST:VSANS:Event:slices_B           //  /G=1 flag prevents interpretation as RGB so 3, 4 slices display correctly
865        ModifyImage slices_B ctab= {*,*,ColdWarm,0}
866        ModifyImage slices_B ctabAutoscale=3
867        ModifyGraph margin(left)=14,margin(bottom)=14,margin(top)=14,margin(right)=14
868        ModifyGraph mirror=2
869        ModifyGraph nticks=4
870        ModifyGraph minor=1
871        ModifyGraph fSize=9
872        ModifyGraph standoff=0
873        ModifyGraph tkLblRot(left)=90
874        ModifyGraph btLen=3
875        ModifyGraph tlOffset=-2
876        RenameWindow #,Event_slice_B
877        SetActiveSubwindow ##
878//
879
880
881End
882
883//
884/////// to copy a sliced data set to a folder to save
885//
886
887
888// load event file from RAW data loaded
889        // pick either the front or middle carriage
890        // pick the "mode" of loading data (osc, stream, etc.)
891// process the event data
892// split to panels
893// move slices to "export" location
894// move bin details to export location
895// repeat load + process + move with the 2nd carriage, using the same time binning
896//
897// save the data file, giving a new name to not overwrite the original data file
898//
899
900
901//
902// root:Packages:NIST:VSANS:RAW:gFileList               //name of the data file(s) in raw (take 1st from semi-list)
903//
904
905Function V_DuplicateRAWForExport()
906        KillDataFolder/Z root:export
907        DuplicateDataFolder root:Packages:NIST:VSANS:RAW: root:export
908        return(0)
909end
910
911Function V_CopySlicesForExport(detStr)
912        String detStr
913       
914        if(cmpstr(detStr,"M") == 0)
915                Duplicate/O root:Packages:NIST:VSANS:Event:slices_B root:export:entry:instrument:detector_MB:slices
916                Duplicate/O root:Packages:NIST:VSANS:Event:slices_T root:export:entry:instrument:detector_MT:slices
917                Duplicate/O root:Packages:NIST:VSANS:Event:slices_L root:export:entry:instrument:detector_ML:slices
918                Duplicate/O root:Packages:NIST:VSANS:Event:slices_R root:export:entry:instrument:detector_MR:slices
919        else
920                Duplicate/O root:Packages:NIST:VSANS:Event:slices_B root:export:entry:instrument:detector_FB:slices
921                Duplicate/O root:Packages:NIST:VSANS:Event:slices_T root:export:entry:instrument:detector_FT:slices
922                Duplicate/O root:Packages:NIST:VSANS:Event:slices_L root:export:entry:instrument:detector_FL:slices
923                Duplicate/O root:Packages:NIST:VSANS:Event:slices_R root:export:entry:instrument:detector_FR:slices
924        endif
925       
926        Duplicate/O root:Packages:NIST:VSANS:Event:binEndTime root:export:entry:reduction:binEndTime
927        Duplicate/O root:Packages:NIST:VSANS:Event:timeWidth root:export:entry:reduction:timeWidth     
928       
929        return(0)
930end
931
932//
933// data is intact in the file so that it can still be read in as a regular raw data file.
934//
935Proc V_SaveExportedEvents()
936
937        String filename = root:Packages:NIST:VSANS:RAW:gFileList                //name of the data file(s) in raw (take 1st from semi-list)
938        String saveName
939
940        saveName = StringFromList(0, fileName+";")
941        Save_VSANS_file("root:export", "Events_"+saveName)
942        Printf "Saved file %s\r","Events_"+saveName
943End
944
945
946
947
948//////////////////////////////////////////////////////////////
949//
950//
951// Panel for reducing event data
952//
953//
954//
955//              Panel to have readout/buttons for:
956//                      # slices
957//                      timing information (table, graph)
958//                      protocol to use (popup)
959//                      Event_ file (popup)
960//
961//                      Manually advance slice and display in RAW (for testing)
962//
963//
964
965//
966//              Save the total monitor count
967//              Save the total count time
968//              Save the sample label
969//
970//              ? Don't need to save the original detector data (I can sum the slices)
971//
972//
973// for each slice(N)
974//              find the binWidth -> bin fraction
975//              adjust count time
976//      adjust monitor count
977//              ? adjust integrated detector count
978//      adjust sample label (mark as slice(N)?)
979//
980//              copy slice(N) to each detector panel (ignore B)
981//
982//              Process through reduction protocol
983//
984//              give appropriate output name (N)
985//
986//
987
988
989//*************************
990//
991// Procedures to allow batch reduction of Event data files
992//
993//****note that much of this file is becoming obsolete as improved methods for
994//reducing multiple files are introduced. Some of these procedures may not last long***
995//
996//**************************
997
998//
999//panel to allow reduction of a series of files using a selected  protocol
1000//
1001//main entry procedure to open the panel, initializing if necessary
1002Proc V_ReduceEventFilesPanel()
1003       
1004        DoWindow/F V_Event_Reduce_Panel
1005        If(V_flag == 0)
1006                V_InitializeEventReducePanel()
1007                //draw panel
1008                V_Event_Reduce_Panel()
1009                //pop the protocol list
1010                V_EVR_ProtoPopMenuProc("",1,"")
1011                //then update the popup list
1012                V_EVR_RedPopMenuProc("ERFilesPopup",1,"")
1013        Endif
1014End
1015
1016//create the global variables needed to run the MReduce Panel
1017//all are kept in root:Packages:NIST:VSANS:Globals:MRED
1018//
1019Proc V_InitializeEventReducePanel()
1020
1021        If(DataFolderExists("root:Packages:NIST:VSANS:Globals:EVRED"))
1022                //ok, do nothing
1023        else
1024                //no, create the folder and the globals
1025                NewDataFolder/O root:Packages:NIST:VSANS:Globals:EVRED
1026//              String/G root:Packages:NIST:VSANS:Globals:MRED:gMRedMatchStr = "*"
1027                PathInfo catPathName
1028                If(V_flag==1)
1029                        String dum = S_path
1030                        String/G root:Packages:NIST:VSANS:Globals:EVRED:gCatPathStr = dum
1031                else
1032                        String/G root:Packages:NIST:VSANS:Globals:EVRED:gCatPathStr = "no path selected"
1033                endif
1034                String/G root:Packages:NIST:VSANS:Globals:EVRED:gMRedList = "none"
1035                String/G root:Packages:NIST:VSANS:Globals:EVRED:gMRProtoList = "none"
1036                String/G root:Packages:NIST:VSANS:Globals:EVRED:gFileNumList=""
1037                Variable/G root:Packages:NIST:VSANS:Globals:EVRED:gNumSlices=1
1038                Variable/G root:Packages:NIST:VSANS:Globals:EVRED:gCurSlice=1
1039
1040
1041        Endif
1042End
1043
1044
1045//
1046// borrows some of the basic functions from the MRED panel
1047//
1048Window V_Event_Reduce_Panel()
1049        Variable sc = 1
1050                       
1051        if(root:Packages:NIST:VSANS:Globals:gLaptopMode == 1)
1052                sc = 0.7
1053        endif
1054       
1055        PauseUpdate; Silent 1           // building window...
1056        NewPanel /W=(535*sc,72*sc,951*sc,288*sc) /K=1 as "Event File File Reduction"
1057        ModifyPanel cbRGB=(60535,51151,51490)
1058        ModifyPanel fixedSize=1
1059        SetDrawLayer UserBack
1060        DrawLine 7*sc,30*sc,422*sc,30*sc
1061        SetVariable PathDisplay,pos={sc*77,7*sc},size={sc*300,13*sc},title="Path"
1062        SetVariable PathDisplay,help={"This is the path to the folder that will be used to find the SANS data while reducing. If no files appear in the popup, make sure that this folder is set correctly"}
1063        SetVariable PathDisplay,limits={-Inf,Inf,0},value= root:Packages:NIST:VSANS:Globals:EVRED:gCatPathStr
1064        Button PathButton,pos={sc*3,3*sc},size={sc*70,20*sc},proc=V_PickEVRPathButton,title="Pick Path"
1065        Button PathButton,help={"Select the folder containing the raw SANS data files"}
1066        Button helpButton,pos={sc*385,3*sc},size={sc*25,20*sc},proc=V_ShowEVRHelp,title="?"
1067        Button helpButton,help={"Show the help file for reducing event files"}
1068        PopupMenu ERFilesPopup,pos={sc*3,45*sc},size={sc*167,19*sc},proc=V_EVR_RedPopMenuProc,title="File to Reduce"
1069        PopupMenu ERFilesPopup,help={"The displayed file is the one that will be reduced."}
1070        PopupMenu ERFilesPopup,mode=1,popvalue="none",value= #"root:Packages:NIST:VSANS:Globals:EVRED:gMRedList"
1071
1072        SetVariable ERSlices,pos={sc*3,75*sc},size={sc*100,15*sc},title="# of slices"
1073        SetVariable ERSlices,limits={0,1000,0},value=root:Packages:NIST:VSANS:Globals:EVRED:gNumSlices
1074       
1075        SetVariable ERSelSlice,pos={sc*150,75*sc},size={sc*100,15*sc},title="current slice"
1076        SetVariable ERSelSlice,limits={0,1000,1},value=root:Packages:NIST:VSANS:Globals:EVRED:gCurSlice
1077        SetVariable ERSelSlice,proc=V_ChangeSliceViewSetVar
1078
1079        Button ToSTOButton,pos={sc*305,45*sc},size={sc*100,20*sc},proc=V_EVR_LoadAndSTO,title="Load to STO"
1080        Button ToSTOButton,help={"Load the event file and copy to STO"}
1081
1082        Button TimeBinButton,pos={sc*305,75*sc},size={sc*100,20*sc},proc=V_EVR_TimeBins,title="Time Bins"
1083        Button TimeBinButton,help={"Display the time bins"}
1084                               
1085//      SetVariable ERList,pos={sc*3,48*sc},size={sc*350,13*sc},proc=V_FileNumberListProc,title="File number list: "
1086//      SetVariable ERList,help={"Enter a comma delimited list of file numbers to reduce. Ranges can be entered using a dash."}
1087//      SetVariable ERList,limits={-Inf,Inf,1},value= root:Packages:NIST:VSANS:Globals:EVRED:gFileNumList
1088
1089        PopupMenu ERProto_pop,pos={sc*3,118*sc},size={sc*119,19*sc},proc=V_EVR_ProtoPopMenuProc,title="Protocol "
1090        PopupMenu ERProto_pop,help={"All of the data files in the popup will be reduced using this protocol"}
1091        PopupMenu ERProto_pop,mode=1,popvalue="none",value= #"root:Packages:NIST:VSANS:Globals:EVRED:gMRProtoList"
1092        Button ReduceAllButton,pos={sc*3,178*sc},size={sc*180,20*sc},proc=V_EVR_ReduceAllSlices,title="Reduce All Slices"
1093        Button ReduceAllButton,help={"This will reduce all slices."}
1094        Button ReduceOneButton,pos={sc*3,148*sc},size={sc*180,20*sc},proc=V_EVR_ReduceTopSlice,title="Reduce Selected Slice"
1095        Button ReduceOneButton,help={"This will reduce the selected slice."}
1096       
1097        Button DoneButton,pos={sc*290,178*sc},size={sc*110,20*sc},proc=V_EVR_DoneButtonProc,title="Done Reducing"
1098        Button DoneButton,help={"When done reducing files, this will close this control panel."}
1099EndMacro
1100
1101
1102//allows the user to set the path to the local folder that contains the SANS data
1103//2 global strings are reset after the path "catPathName" is reset in the function PickPath()
1104// this path is the only one, the globals are simply for convenience
1105//
1106Function V_PickEVRPathButton(PathButton) : ButtonControl
1107        String PathButton
1108       
1109        V_PickPath()            //sets the main global path string for catPathName
1110       
1111        //then update the "local" copy in the MRED subfolder
1112        PathInfo/S catPathName
1113        String dum = S_path
1114        if (V_flag == 0)
1115                //path does not exist - no folder selected
1116                String/G root:Packages:NIST:VSANS:Globals:EVRED:gCatPathStr = "no folder selected"
1117        else
1118                String/G root:Packages:NIST:VSANS:Globals:EVRED:gCatPathStr = dum
1119        endif
1120       
1121        //Update the pathStr variable box
1122        ControlUpdate/W=V_Event_Reduce_Panel $"PathDisplay"
1123       
1124        //then update the popup list
1125        V_EVR_RedPopMenuProc("ERFilesPopup",1,"")
1126End
1127
1128//
1129// loads the file in the popup (to RAW as usual)
1130// then copies the data to STO
1131//
1132//      updates the total number of slices
1133//
1134// resets the slice view to 0
1135//              changes the limits on the SetVar control {0,n,1}
1136//
1137Function V_EVR_LoadAndSTO(PathButton) : ButtonControl
1138        String PathButton
1139
1140        String fileName
1141        Variable err
1142
1143        ControlInfo ERFilesPopup
1144        fileName = S_Value
1145       
1146        err = V_LoadHDF5Data(FileName,"RAW")
1147        if(!err)                //directly from, and the same steps as DisplayMainButtonProc(ctrlName)
1148                SVAR hdfDF = root:file_name                     // last file loaded, may not be the safest way to pass
1149                String folder = StringFromList(0,hdfDF,".")
1150               
1151                // this (in SANS) just passes directly to fRawWindowHook()
1152                V_UpdateDisplayInformation("RAW")               // plot the data in whatever folder type
1153                                                               
1154                // set the global to display ONLY if the load was called from here, not from the
1155                // other routines that load data (to read in values)
1156                SVAR gLast = root:Packages:NIST:VSANS:Globals:gLastLoadedFile
1157                gLast = hdfDF
1158                                               
1159        endif
1160       
1161        // now copy RAW to STO for safe keeping...
1162        //V_CopyHDFToWorkFolder(oldtype,newtype)
1163        V_CopyHDFToWorkFolder("RAW","STO")
1164
1165        // read the number of slices from FL
1166        WAVE/Z w = root:Packages:NIST:VSANS:RAW:entry:instrument:detector_FL:slices
1167        NVAR num = root:Packages:NIST:VSANS:Globals:EVRED:gNumSlices
1168       
1169        num = DimSize(w, 2)
1170       
1171        //change the slice view to slice 0
1172        SetVariable ERSelSlice,win=V_Event_Reduce_Panel,limits={0,(num-1),1}
1173        NVAR value=root:Packages:NIST:VSANS:Globals:EVRED:gCurSlice
1174        value=0
1175        V_ChangeSliceViewSetVar("",0,"","")
1176       
1177        return(0)
1178End
1179
1180// given a file already loaded into RAW (and copied to STO)
1181// display a selected slice (8 panels)
1182// rescale the monitor count
1183// rescale the count time
1184// update the sample label
1185//
1186// TODO -- and I missing anything that is done at the normal RAW load time
1187// that I am not doing here simply by copying over
1188// -- like... data error, nonlinear corrections, etc.
1189// the nonlinear corrections need only be done once, since the detector is the same for all slices.
1190//
1191Function V_ChangeSliceViewSetVar(ctrlName,varNum,varStr,varName) : SetVariableControl
1192        String ctrlName
1193        Variable varNum
1194        String varStr
1195        String varName
1196       
1197        Variable ii
1198        String detStr,fname     
1199        // varNum is the only meaningful input, the slice number
1200       
1201        // copy STO to RAW
1202        V_CopyHDFToWorkFolder("STO","RAW")
1203       
1204       
1205        // switch data to point to the correct slice
1206        string tmpStr = "root:Packages:NIST:VSANS:RAW:entry:instrument:"
1207
1208        fname="RAW"
1209        for(ii=0;ii<ItemsInList(ksDetectorListNoB);ii+=1)
1210                detStr = StringFromList(ii, ksDetectorListNoB, ";")
1211                Wave data = V_getDetectorDataW(fname,detStr)
1212               
1213                WAVE/Z slices = $("root:Packages:NIST:VSANS:RAW:entry:instrument:detector_"+detStr+":slices")
1214                data = slices[p][q][varNum]
1215                V_MakeDataError(tmpStr+"detector_"+detStr)              //update the error wave to match the slice
1216        endfor
1217               
1218        // TODO: update the times and counts
1219        // use a special "put", not "write" so it is written to the RAW folder, not the file
1220        //
1221        wave binEnd = root:Packages:NIST:VSANS:RAW:entry:reduction:binEndTime
1222        wave timeWidth = root:Packages:NIST:VSANS:RAW:entry:reduction:timeWidth
1223       
1224        Variable timeFract,num
1225        num = numpnts(binEnd)
1226        timeFract = timeWidth[varNum]/binEnd[num-1]
1227
1228// get values from STO
1229        Variable mon_STO,ctTime_STO
1230        String label_STO
1231
1232        ctTime_STO = V_getCount_time("STO")
1233        mon_STO = V_getBeamMonNormData("STO")
1234        label_STO = V_getSampleDescription("STO")
1235       
1236// mon ct
1237        V_putBeamMonNormData("RAW",mon_STO*timeFract)
1238// ct time
1239        V_putCount_time("RAW",ctTime_STO*timeFract)
1240// label
1241        V_putSampleDescription("RAW",label_STO+" slice "+num2str(varNum))
1242       
1243        return(0)
1244End
1245
1246
1247//
1248// locates the time bins and shows the time bin table (and plot?)
1249//
1250// Can't show the plot of counts/bin since there would be 8 of these now, one for
1251// each panel. Could show a total count per slice, but the numbers (binCount) is currently
1252// not written to the Event_ file.
1253//
1254// the macro that is called from the main Event panel shows the total counts/bin for the carriage
1255// that is active. Maybe this would be OK, but then there are still two sets of data, one for
1256// Front and one for Middle...
1257//
1258Function V_EVR_TimeBins(PathButton) : ButtonControl
1259        String PathButton
1260
1261        wave binEnd = root:Packages:NIST:VSANS:RAW:entry:reduction:binEndTime
1262        wave timeWidth = root:Packages:NIST:VSANS:RAW:entry:reduction:timeWidth
1263
1264        edit binEnd,timeWidth
1265       
1266//      DoWindow/F V_EventBarGraph
1267//      if(V_flag == 0)
1268//              PauseUpdate; Silent 1           // building window...
1269//              String fldrSav0= GetDataFolder(1)
1270//              SetDataFolder root:Packages:NIST:VSANS:Event:
1271//              Display /W=(110,705,610,1132)/N=V_EventBarGraph /K=1 binCount vs binEndTime
1272//              SetDataFolder fldrSav0
1273//              ModifyGraph mode=5
1274//              ModifyGraph marker=19
1275//              ModifyGraph lSize=2
1276//              ModifyGraph rgb=(0,0,0)
1277//              ModifyGraph msize=2
1278//              ModifyGraph hbFill=2
1279//              ModifyGraph gaps=0
1280//              ModifyGraph usePlusRGB=1
1281//              ModifyGraph toMode=0
1282//              ModifyGraph useBarStrokeRGB=1
1283//              ModifyGraph standoff=0
1284//              SetAxis left 0,*
1285//              Label bottom "\\Z14Time (seconds)"
1286//              Label left "\\Z14Number of Events"
1287//      endif
1288       
1289       
1290        return(0)
1291End
1292
1293Proc V_ShowEVRHelp(ctrlName) : ButtonControl
1294        String ctrlName
1295
1296        DisplayHelpTopic/Z/K=1 "VSANS Data Reduction Documentation[Reducing Event Data]"
1297        if(V_flag !=0)
1298                DoAlert 0,"The VSANS Data Reduction Tutorial Help file could not be found"
1299        endif
1300End
1301
1302
1303
1304
1305//
1306//
1307//
1308Function V_EVR_RedPopMenuProc(ERFilesPopup,popNum,popStr) : PopupMenuControl
1309        String ERFilesPopup
1310        Variable popNum
1311        String popStr
1312
1313        String list = V_GetValidEVRedPopupList()
1314//     
1315        SVAR str= root:Packages:NIST:VSANS:Globals:EVRED:gMredList
1316        str=list
1317        ControlUpdate ERFilesPopup
1318        return(0)
1319End
1320
1321// get a  list of all of the sample files, based on intent
1322//
1323//
1324// only accepts files in the list that are purpose=scattering
1325//
1326Function/S V_GetValidEVRedPopupList()
1327
1328        String semiList=""
1329
1330        semiList = V_GetSAMList()
1331        return(semiList)
1332
1333End
1334
1335//returns a list of the available protocol waves in the protocols folder
1336//removes "CreateNew", "tempProtocol" and "fakeProtocol" from list (if they exist)
1337//since these waves do not contain valid protocol instructions
1338//
1339// also removes Base and DoAll since for event file reduction, speed is of the essence
1340// and there is no provision in the protocol for "asking" for the files to be identified
1341//
1342Function V_EVR_ProtoPopMenuProc(ERProto_pop,popNum,popStr) : PopupMenuControl
1343        String ERProto_pop
1344        Variable popNum
1345        String popStr
1346
1347        //get list of currently valid protocols, and put it in the popup (the global list)
1348        //excluding "tempProtocol" and "CreateNew" if they exist
1349        SetDataFolder root:Packages:NIST:VSANS:Globals:Protocols
1350        String list = WaveList("*",";","")
1351        SetDataFolder root:
1352       
1353        //remove items from the list (list is unchanged if the items are not present)
1354        list = RemoveFromList("CreateNew", list, ";")
1355        list = RemoveFromList("tempProtocol", list, ";")
1356        list = RemoveFromList("fakeProtocol", list, ";")
1357        list = RemoveFromList("PanelNameW", list, ";")
1358        list = RemoveFromList("Beg_pts", list, ";")
1359        list = RemoveFromList("End_pts", list, ";")
1360        list = RemoveFromList("trimUpdate", list, ";")
1361        list = RemoveFromList("Base", list, ";")
1362        list = RemoveFromList("DoAll", list, ";")
1363       
1364        String/G root:Packages:NIST:VSANS:Globals:EVRED:gMRProtoList = list
1365        ControlUpdate ERProto_pop
1366
1367End
1368
1369//
1370//button procedure to close the panel,
1371//
1372Function V_EVR_DoneButtonProc(ctrlName) : ButtonControl
1373        String ctrlName
1374
1375        // this button will make sure all files are closed
1376        //and close the panel
1377
1378        Close/A
1379        DoWindow/K V_Event_Reduce_Panel
1380       
1381        KillDataFolder root:Packages:NIST:VSANS:Globals:EVRED
1382End
1383
1384
1385
1386
1387//
1388// reduce just the selected slice
1389//
1390// Assumes that:
1391// - the event data file has been loaded and copied to STO for repeated access
1392// - the protocol has been properly and completely defined (test one slice first!)
1393//
1394//
1395Function V_EVR_ReduceTopSlice(ctrlName) : ButtonControl
1396        String ctrlName
1397
1398        //get the selected protocol
1399        ControlInfo ERProto_pop
1400        String protocolNameStr = S_Value
1401       
1402        //also set this as the current protocol, for the function that writes the averaged waves
1403        String/G root:Packages:NIST:VSANS:Globals:Protocols:gProtoStr = protocolNameStr
1404       
1405        // get the file name from the popup
1406        ControlInfo ERFilesPopup
1407        String samStr = S_Value
1408       
1409        // get the current slice number
1410        NVAR curSlice = root:Packages:NIST:VSANS:Globals:EVRED:gCurSlice
1411        // get the total number of slices
1412        NVAR totalSlices = root:Packages:NIST:VSANS:Globals:EVRED:gNumSlices
1413       
1414        //reduce all the files in the list here, using the global protocol(the full reference)
1415        //see -- DoReduceList is found in MultipleReduce.ipf
1416       
1417//      V_DoReduceList(commaList)
1418        Variable skipLoad = 0
1419        V_ExecuteProtocol_Event(protocolNameStr,samStr,curSlice,skipLoad)
1420       
1421        Return 0
1422End
1423
1424
1425
1426//
1427// reduce all slices
1428//
1429Function V_EVR_ReduceAllSlices(ctrlName) : ButtonControl
1430        String ctrlName
1431
1432        //get the selected protocol
1433        ControlInfo ERProto_pop
1434        String protocolNameStr = S_Value
1435       
1436        //also set this as the current protocol, for the function that writes the averaged waves
1437        String/G root:Packages:NIST:VSANS:Globals:Protocols:gProtoStr = protocolNameStr
1438       
1439        // get the file name from the popup
1440        ControlInfo ERFilesPopup
1441        String samStr = S_Value
1442       
1443        // get the total number of slices
1444        NVAR totalSlices = root:Packages:NIST:VSANS:Globals:EVRED:gNumSlices
1445       
1446       
1447        Variable skipLoad = 0
1448        Variable curSlice = 0
1449        // do the first one (slice 0)
1450        V_ExecuteProtocol_Event(protocolNameStr,samStr,curSlice,skipLoad)
1451       
1452        skipLoad = 1
1453        for(curSlice = 1;curSlice<totalSlices; curSlice +=1)
1454                V_ExecuteProtocol_Event(protocolNameStr,samStr,curSlice,skipLoad)
1455        endfor
1456       
1457       
1458        Return 0
1459End
1460
1461
1462
1463//////////////////////////////////
1464//
1465// This is the Event-equivalent version of ExecuteProtocol
1466// with special handling for shuffling the event slices from STO to RAW->SAM
1467// -skips repetitive loads
1468// -adjusts timing
1469// -names slices
1470
1471//protStr is the full path to the selected protocol wave
1472//samStr is the name of the event data file "Event_sansNNNN.nxs.ngv"
1473// SliceNum is the number of slice to reduce (copy it from STO)
1474// skipLoad is a flag (0|1) to allow skip of loading EMP, BGD, etc. on repeated passes
1475Function V_ExecuteProtocol_Event(protStr,samStr,sliceNum,skipLoad)
1476        String protStr,samStr
1477        Variable sliceNum
1478        Variable skipLoad
1479
1480        String protoPath = "root:Packages:NIST:VSANS:Globals:Protocols:"
1481        WAVE/T prot = $(protoPath+protStr)
1482//      SetDataFolder root:Packages:NIST:VSANS:Globals:Protocols
1483       
1484        Variable filesOK,err,notDone
1485        String activeType, msgStr, junkStr, pathStr=""
1486        PathInfo catPathName                    //this is where the files are
1487        pathStr=S_path
1488       
1489//      NVAR useXMLOutput = root:Packages:NIST:gXML_Write
1490       
1491        //Parse the instructions in the prot wave
1492        //0 - bkg
1493        //1 - emp
1494        //2 - div
1495        //3 - mask
1496        //4 - abs params c2-c5
1497        //5 - average params
1498        //6 = DRK file (**out of sequence)
1499        //7 = beginning trim points
1500        //8 = end trim points
1501        //9 = unused
1502        //10 = unused
1503        //11 = unused
1504
1505//////////////////////////////
1506// DIV
1507//////////////////////////////
1508// for VSANS, DIV is used on each data file as it is converted to WORK, so it needs to be
1509//  the first thing in place, before any data or backgrounds are loaded
1510
1511        //check for work.div file (prot[2])
1512        //load in if needed
1513        // no math is done here, DIV is applied as files are converted to WORK (the first operation in VSANS)
1514        //
1515                // save the state of the DIV preference
1516        NVAR gDoDIVCor = root:Packages:NIST:VSANS:Globals:gDoDIVCor
1517        Variable saved_gDoDIVCor = gDoDIVCor
1518       
1519        if(!skipLoad)
1520               
1521                err = V_Proto_LoadDIV(prot[2])
1522               
1523                if(err)
1524                        SetDataFolder root:
1525                        Abort "No file selected, data reduction aborted"
1526                endif
1527        endif
1528       
1529//////////////////////////////
1530// SAM
1531//////////////////////////////
1532
1533        // move the selected slice number to RAW, then to SAM
1534        V_ChangeSliceViewSetVar("",sliceNum,"","")
1535       
1536        //Execute "V_Convert_to_Workfile()"
1537        err = V_Raw_to_work("SAM")
1538       
1539        //always update
1540        activeType = "SAM"
1541        V_UpdateDisplayInformation(ActiveType)
1542
1543
1544//////////////////////////////
1545// BGD
1546//////////////////////////////
1547       
1548        //check for BGD file  -- "ask" might not fail - "ask?" will - ? not allowed in VAX filenames
1549        // add if needed
1550        //use a "case" statement
1551        if(!skipLoad)
1552       
1553                msgStr = "Select background file"
1554                activeType = "BGD"
1555               
1556                err = V_Proto_LoadFile(prot[0],activeType,msgStr)
1557                if(err)
1558                        PathInfo/S catPathName
1559                        SetDataFolder root:
1560                        Abort "No file selected, data reduction aborted"
1561                endif
1562       
1563        //      //Loader is in charge of updating, since it knows if data was loaded
1564        //      V_UpdateDisplayInformation(ActiveType)
1565        endif
1566
1567//////////////////////////////
1568// EMP
1569////////////////////////////// 
1570       
1571        //check for emp file (prot[1])
1572        // add if needed
1573        if(!skipLoad)
1574
1575                msgStr = "Select empty cell data"
1576                activeType = "EMP"
1577               
1578                err = V_Proto_LoadFile(prot[1],activeType,msgStr)
1579                if(err)
1580                        PathInfo/S catPathName
1581                        SetDataFolder root:
1582                        Abort "No file selected, data reduction aborted"
1583                endif
1584       
1585        //      //Loader is in charge of updating, since it knows if data was loaded
1586        //      V_UpdateDisplayInformation(ActiveType)
1587        endif
1588
1589//////////////////////////////
1590// CORRECT
1591//////////////////////////////
1592
1593        //do the CORRECT step based on the answers to emp and bkg subtraction
1594        //by setting the proper"mode"
1595        //1 = both emp and bgd subtraction
1596        //2 = only bgd subtraction
1597        //3 = only emp subtraction
1598        //4 = no subtraction
1599        //additional modes 091301
1600        //11 = emp, bgd, drk
1601        //12 = bgd and drk
1602        //13 = emp and drk
1603        //14 = no subtractions
1604        //work.drk is from proto[6]
1605        //
1606        //subtracting just the DRK data is NOT an option - it doesnt' really make any physical sense
1607        // - in this case, DRK is skipped (equivalent to mode==4)
1608        // automatically accounts for attenuators given the lookup tables and the
1609        //desired subtractions
1610        //Attenuator lookup tables are alredy implemented (NG1 = NG7)
1611        //
1612
1613
1614/////// DRK is SKIPPED
1615       
1616//      //read in the DRK data if necessary
1617//      //only one file, assumed to be RAW data
1618//      //
1619//      String fname="",drkStr=""
1620//      drkStr=StringByKey("DRK",prot[6],"=",",")
1621//      if(cmpstr(drkStr,"none") != 0)
1622//              err = ReadHeaderAndData( (pathStr+drkStr) )
1623//              if(err)
1624//                      PathInfo/S catPathName
1625//                      Abort "reduction sequence aborted"
1626//              endif
1627//              err = V_Raw_to_Work_NoNorm("DRK")
1628//      endif
1629
1630        //dispatch to the proper "mode" of Correct()
1631//      V_Dispatch_to_Correct(bgdStr,empStr,drkStr)
1632        V_Dispatch_to_Correct(prot[0],prot[1],prot[6])
1633       
1634        if(err)
1635                PathInfo/S catPathName
1636                SetDataFolder root:
1637                Abort "error in Correct, called from executeprotocol, normal cor"
1638        endif
1639        activeType = "COR"
1640
1641// always update - COR will always be generated
1642        V_UpdateDisplayInformation(ActiveType)         
1643
1644
1645//////////////////////////////
1646//  ABSOLUTE SCALE
1647//////////////////////////////
1648
1649        err = V_Proto_ABS_Scale(prot[4],activeType)
1650       
1651        if(err)
1652                SetDataFolder root:
1653                Abort "Error in V_Absolute_Scale(), called from V_ExecuteProtocol"
1654        endif
1655//      activeType = "ABS"
1656
1657
1658//////////////////////////////
1659// MASK
1660//////////////////////////////
1661//
1662// DONE
1663//              x- fill in the "ask" step
1664//  x- none is OK, except if the kill fails for any reason
1665// x- the regular case of the file name specified by the protocol works correctly
1666// x- don't create a null mask if not used, it will handle the error and print out that the mask is missing
1667//
1668//mask data if desired (mask is applied when the data is binned to I(q)) and is
1669//not done explicitly here
1670       
1671        //check for mask
1672        //doesn't change the activeType
1673        if(!skipLoad)
1674
1675                V_Proto_ReadMask(prot[3])
1676        endif
1677       
1678//////////////////////////////
1679// AVERAGING
1680//////////////////////////////
1681
1682        // average/save data as specified
1683        //Parse the keyword=<Value> string as needed, based on AVTYPE
1684       
1685        //average/plot first
1686        String av_type = StringByKey("AVTYPE",prot[5],"=",";")
1687        If(cmpstr(av_type,"none") != 0)
1688                If (cmpstr(av_type,"")==0)              //if the key could not be found... (if "ask" the string)
1689                        //get the averaging parameters from the user, as if the set button was hit in the panel
1690                        V_SetAverageParamsButtonProc("dummy")           //from "ProtocolAsPanel"
1691                        SVAR tempAveStr = root:Packages:NIST:VSANS:Globals:Protocols:gAvgInfoStr
1692                        av_type = StringByKey("AVTYPE",tempAveStr,"=",";")
1693                else
1694                        //there is info in the string, use the protocol
1695                        //set the global keyword-string to prot[5]
1696                        String/G root:Packages:NIST:VSANS:Globals:Protocols:gAvgInfoStr = prot[5]
1697                Endif
1698        Endif
1699
1700
1701        String detGroup = StringByKey("DETGROUP",prot[5],"=",";")               //only for annular, null if not present
1702
1703       
1704//convert the folder to linear scale before averaging, then revert by calling the window hook
1705// (not needed for VSANS, data is always linear scale)
1706
1707//
1708// (DONE)
1709// -x this generates a "Bin Type Not Found" error if reducing only to a 2D level (like for DIV)
1710//              because binTypeStr is null
1711        String binTypeStr = StringByKey("BINTYPE",prot[5],"=",";")
1712        // plotting is not really necessary, and the graph may not be open - so skip for now?
1713        Variable binType
1714        // only get the binning type if user asks for averaging
1715        If(cmpstr(av_type,"none") != 0)
1716                binType = V_BinTypeStr2Num(binTypeStr)
1717                if(binType == 0)
1718                                Abort "Binning mode not found in V_QBinAllPanels() "// when no case matches
1719                endif
1720        endif
1721
1722
1723// identify the collimation type
1724// this will be a string used to determine how the resolution information is to be calculated
1725// and written to the reduced data file
1726//
1727// possible values are:
1728//
1729// pinhole
1730// pinhole_whiteBeam
1731// narrowSlit
1732// narrowSlit_whiteBeam
1733// convergingPinholes
1734//
1735
1736        String collimationStr
1737        collimationStr = V_IdentifyCollimation(activeType)
1738       
1739
1740////////////////////////////////////////
1741// DISPATCH TO AVERAGING
1742/////////////////////////////////////////
1743//
1744// TODO:
1745// -- do I calculate the proper resolution here?, YES, I've already decoded the binning type
1746//   and the averaging type has been specified by the protocol.
1747//
1748// so currently, the resolution is calculated every time that the data is averaged (in VC_fDoBinning_QxQy2D)
1749//
1750// -- if I calculate the resolution here, then the Trimming routines must be updated
1751//    to trim the resolution waves also. This will work for the columns present in
1752//    pinhole resolution, but anything using the matrix method - it won't work - and I'll need
1753//    a different solution
1754//
1755
1756        V_Proto_doAverage(prot[5],av_type,activeType,binType,collimationStr)
1757
1758
1759
1760////////////////////////
1761// PLOT THE DATA
1762////////////////////////
1763
1764        V_Proto_doPlot(prot[5],av_type,activeType,binType,detGroup)
1765       
1766       
1767
1768////////////////////   
1769// SAVE THE DATA
1770////////////////////
1771
1772//
1773// x- how do I get the sample file name?
1774//    local variable samFileLoaded is the file name loaded (contains the extension)
1775//
1776// V_Proto_SaveFile(avgStr,activeType,samFileLoaded,av_type,binType,detGroup,trimBegStr,trimEndStr)
1777
1778        prot[9] = collimationStr
1779        String outputFileName
1780        outputFileName = RemoveEnding(samStr,".nxs.ngv") + "_SL"+num2str(sliceNum)
1781        //? remove the "Events_" from the beginning? some other naming scheme entirely?
1782       
1783        V_Proto_SaveFile(prot[5],activeType,outputFileName,av_type,binType,detGroup,prot[7],prot[8])
1784       
1785//////////////////////////////
1786// DONE WITH THE PROTOCOL
1787////////////////////////////// 
1788       
1789        // reset any global preferences that I had changed
1790        gDoDIVCor = saved_gDoDIVCor
1791       
1792       
1793        Return(0)
1794End
1795
1796
1797
Note: See TracBrowser for help on using the repository browser.