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

Last change on this file since 1203 was 1203, checked in by srkline, 3 years ago

Corrected attenuator table for VSANS to include the range 4.52->19. Patching of the attenuation factor is disabled since the factor is always calculated rather than read from the file.

Added a few help links in preparation for the full help file integration

Added a "super" white beam distribution definition and a single model function for testing of this new mode. Still need the normalization and mean wavelength for the distribution + a way to identify it in the file metadata.

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