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

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

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

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