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

Last change on this file since 1130 was 1114, checked in by srkline, 4 years ago

bug fixes for:

RealTime? updating at VSANS
Mask loading at SANS

added highResGain field for VSANS R/W

File size: 46.3 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="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//
1242Function V_EVR_TimeBins(PathButton) : ButtonControl
1243        String PathButton
1244
1245        wave binEnd = root:Packages:NIST:VSANS:RAW:entry:reduction:binEndTime
1246        wave timeWidth = root:Packages:NIST:VSANS:RAW:entry:reduction:timeWidth
1247
1248        edit binEnd,timeWidth
1249       
1250        return(0)
1251End
1252
1253Proc V_ShowEVRHelp(ctrlName) : ButtonControl
1254        String ctrlName
1255
1256        DisplayHelpTopic/Z/K=1 "VSANS Data Reduction Tutorial[Reduce Event Files]"
1257        if(V_flag !=0)
1258                DoAlert 0,"The VSANS Data Reduction Tutorial Help file could not be found"
1259        endif
1260End
1261
1262
1263
1264
1265//
1266//
1267//
1268Function V_EVR_RedPopMenuProc(ERFilesPopup,popNum,popStr) : PopupMenuControl
1269        String ERFilesPopup
1270        Variable popNum
1271        String popStr
1272
1273        String list = V_GetValidEVRedPopupList()
1274//     
1275        SVAR str= root:Packages:NIST:VSANS:Globals:EVRED:gMredList
1276        str=list
1277        ControlUpdate ERFilesPopup
1278        return(0)
1279End
1280
1281// get a  list of all of the sample files, based on intent
1282//
1283//
1284// only accepts files in the list that are purpose=scattering
1285//
1286Function/S V_GetValidEVRedPopupList()
1287
1288        String semiList=""
1289
1290        semiList = V_GetSAMList()
1291        return(semiList)
1292
1293End
1294
1295//returns a list of the available protocol waves in the protocols folder
1296//removes "CreateNew", "tempProtocol" and "fakeProtocol" from list (if they exist)
1297//since these waves do not contain valid protocol instructions
1298//
1299// also removes Base and DoAll since for event file reduction, speed is of the essence
1300// and there is no provision in the protocol for "asking" for the files to be identified
1301//
1302Function V_EVR_ProtoPopMenuProc(ERProto_pop,popNum,popStr) : PopupMenuControl
1303        String ERProto_pop
1304        Variable popNum
1305        String popStr
1306
1307        //get list of currently valid protocols, and put it in the popup (the global list)
1308        //excluding "tempProtocol" and "CreateNew" if they exist
1309        SetDataFolder root:Packages:NIST:VSANS:Globals:Protocols
1310        String list = WaveList("*",";","")
1311        SetDataFolder root:
1312       
1313        //remove items from the list (list is unchanged if the items are not present)
1314        list = RemoveFromList("CreateNew", list, ";")
1315        list = RemoveFromList("tempProtocol", list, ";")
1316        list = RemoveFromList("fakeProtocol", list, ";")
1317        list = RemoveFromList("PanelNameW", list, ";")
1318        list = RemoveFromList("Beg_pts", list, ";")
1319        list = RemoveFromList("End_pts", list, ";")
1320        list = RemoveFromList("trimUpdate", list, ";")
1321        list = RemoveFromList("Base", list, ";")
1322        list = RemoveFromList("DoAll", list, ";")
1323       
1324        String/G root:Packages:NIST:VSANS:Globals:EVRED:gMRProtoList = list
1325        ControlUpdate ERProto_pop
1326
1327End
1328
1329//
1330//button procedure to close the panel,
1331//
1332Function V_EVR_DoneButtonProc(ctrlName) : ButtonControl
1333        String ctrlName
1334
1335        // this button will make sure all files are closed
1336        //and close the panel
1337
1338        Close/A
1339        DoWindow/K V_Event_Reduce_Panel
1340       
1341        KillDataFolder root:Packages:NIST:VSANS:Globals:EVRED
1342End
1343
1344
1345
1346
1347//
1348// reduce just the selected slice
1349//
1350// Assumes that:
1351// - the event data file has been loaded and copied to STO for repeated access
1352// - the protocol has been properly and completely defined (test one slice first!)
1353//
1354//
1355Function V_EVR_ReduceTopSlice(ctrlName) : ButtonControl
1356        String ctrlName
1357
1358        //get the selected protocol
1359        ControlInfo ERProto_pop
1360        String protocolNameStr = S_Value
1361       
1362        //also set this as the current protocol, for the function that writes the averaged waves
1363        String/G root:Packages:NIST:VSANS:Globals:Protocols:gProtoStr = protocolNameStr
1364       
1365        // get the file name from the popup
1366        ControlInfo ERFilesPopup
1367        String samStr = S_Value
1368       
1369        // get the current slice number
1370        NVAR curSlice = root:Packages:NIST:VSANS:Globals:EVRED:gCurSlice
1371        // get the total number of slices
1372        NVAR totalSlices = root:Packages:NIST:VSANS:Globals:EVRED:gNumSlices
1373       
1374        //reduce all the files in the list here, using the global protocol(the full reference)
1375        //see -- DoReduceList is found in MultipleReduce.ipf
1376       
1377//      V_DoReduceList(commaList)
1378        Variable skipLoad = 0
1379        V_ExecuteProtocol_Event(protocolNameStr,samStr,curSlice,skipLoad)
1380       
1381        Return 0
1382End
1383
1384
1385
1386//
1387// reduce all slices
1388//
1389Function V_EVR_ReduceAllSlices(ctrlName) : ButtonControl
1390        String ctrlName
1391
1392        //get the selected protocol
1393        ControlInfo ERProto_pop
1394        String protocolNameStr = S_Value
1395       
1396        //also set this as the current protocol, for the function that writes the averaged waves
1397        String/G root:Packages:NIST:VSANS:Globals:Protocols:gProtoStr = protocolNameStr
1398       
1399        // get the file name from the popup
1400        ControlInfo ERFilesPopup
1401        String samStr = S_Value
1402       
1403        // get the total number of slices
1404        NVAR totalSlices = root:Packages:NIST:VSANS:Globals:EVRED:gNumSlices
1405       
1406       
1407        Variable skipLoad = 0
1408        Variable curSlice = 0
1409        // do the first one (slice 0)
1410        V_ExecuteProtocol_Event(protocolNameStr,samStr,curSlice,skipLoad)
1411       
1412        skipLoad = 1
1413        for(curSlice = 1;curSlice<totalSlices; curSlice +=1)
1414                V_ExecuteProtocol_Event(protocolNameStr,samStr,curSlice,skipLoad)
1415        endfor
1416       
1417       
1418        Return 0
1419End
1420
1421
1422
1423//////////////////////////////////
1424//
1425// This is the Event-equivalent version of ExecuteProtocol
1426// with special handling for shuffling the event slices from STO to RAW->SAM
1427// -skips repetitive loads
1428// -adjusts timing
1429// -names slices
1430
1431//protStr is the full path to the selected protocol wave
1432//samStr is the name of the event data file "Event_sansNNNN.nxs.ngv"
1433// SliceNum is the number of slice to reduce (copy it from STO)
1434// skipLoad is a flag (0|1) to allow skip of loading EMP, BGD, etc. on repeated passes
1435Function V_ExecuteProtocol_Event(protStr,samStr,sliceNum,skipLoad)
1436        String protStr,samStr
1437        Variable sliceNum
1438        Variable skipLoad
1439
1440        String protoPath = "root:Packages:NIST:VSANS:Globals:Protocols:"
1441        WAVE/T prot = $(protoPath+protStr)
1442//      SetDataFolder root:Packages:NIST:VSANS:Globals:Protocols
1443       
1444        Variable filesOK,err,notDone
1445        String activeType, msgStr, junkStr, pathStr=""
1446        PathInfo catPathName                    //this is where the files are
1447        pathStr=S_path
1448       
1449//      NVAR useXMLOutput = root:Packages:NIST:gXML_Write
1450       
1451        //Parse the instructions in the prot wave
1452        //0 - bkg
1453        //1 - emp
1454        //2 - div
1455        //3 - mask
1456        //4 - abs params c2-c5
1457        //5 - average params
1458        //6 = DRK file (**out of sequence)
1459        //7 = beginning trim points
1460        //8 = end trim points
1461        //9 = unused
1462        //10 = unused
1463        //11 = unused
1464
1465//////////////////////////////
1466// DIV
1467//////////////////////////////
1468// for VSANS, DIV is used on each data file as it is converted to WORK, so it needs to be
1469//  the first thing in place, before any data or backgrounds are loaded
1470
1471        //check for work.div file (prot[2])
1472        //load in if needed
1473        // no math is done here, DIV is applied as files are converted to WORK (the first operation in VSANS)
1474        //
1475                // save the state of the DIV preference
1476        NVAR gDoDIVCor = root:Packages:NIST:VSANS:Globals:gDoDIVCor
1477        Variable saved_gDoDIVCor = gDoDIVCor
1478       
1479        if(!skipLoad)
1480               
1481                err = V_Proto_LoadDIV(prot[2])
1482               
1483                if(err)
1484                        SetDataFolder root:
1485                        Abort "No file selected, data reduction aborted"
1486                endif
1487        endif
1488       
1489//////////////////////////////
1490// SAM
1491//////////////////////////////
1492
1493        // move the selected slice number to RAW, then to SAM
1494        V_ChangeSliceViewSetVar("",sliceNum,"","")
1495       
1496        //Execute "V_Convert_to_Workfile()"
1497        err = V_Raw_to_work("SAM")
1498       
1499        //always update
1500        activeType = "SAM"
1501        V_UpdateDisplayInformation(ActiveType)
1502
1503
1504//////////////////////////////
1505// BGD
1506//////////////////////////////
1507       
1508        //check for BGD file  -- "ask" might not fail - "ask?" will - ? not allowed in VAX filenames
1509        // add if needed
1510        //use a "case" statement
1511        if(!skipLoad)
1512       
1513                msgStr = "Select background file"
1514                activeType = "BGD"
1515               
1516                err = V_Proto_LoadFile(prot[0],activeType,msgStr)
1517                if(err)
1518                        PathInfo/S catPathName
1519                        SetDataFolder root:
1520                        Abort "No file selected, data reduction aborted"
1521                endif
1522       
1523        //      //Loader is in charge of updating, since it knows if data was loaded
1524        //      V_UpdateDisplayInformation(ActiveType)
1525        endif
1526
1527//////////////////////////////
1528// EMP
1529////////////////////////////// 
1530       
1531        //check for emp file (prot[1])
1532        // add if needed
1533        if(!skipLoad)
1534
1535                msgStr = "Select empty cell data"
1536                activeType = "EMP"
1537               
1538                err = V_Proto_LoadFile(prot[1],activeType,msgStr)
1539                if(err)
1540                        PathInfo/S catPathName
1541                        SetDataFolder root:
1542                        Abort "No file selected, data reduction aborted"
1543                endif
1544       
1545        //      //Loader is in charge of updating, since it knows if data was loaded
1546        //      V_UpdateDisplayInformation(ActiveType)
1547        endif
1548
1549//////////////////////////////
1550// CORRECT
1551//////////////////////////////
1552
1553        //do the CORRECT step based on the answers to emp and bkg subtraction
1554        //by setting the proper"mode"
1555        //1 = both emp and bgd subtraction
1556        //2 = only bgd subtraction
1557        //3 = only emp subtraction
1558        //4 = no subtraction
1559        //additional modes 091301
1560        //11 = emp, bgd, drk
1561        //12 = bgd and drk
1562        //13 = emp and drk
1563        //14 = no subtractions
1564        //work.drk is from proto[6]
1565        //
1566        //subtracting just the DRK data is NOT an option - it doesnt' really make any physical sense
1567        // - in this case, DRK is skipped (equivalent to mode==4)
1568        // automatically accounts for attenuators given the lookup tables and the
1569        //desired subtractions
1570        //Attenuator lookup tables are alredy implemented (NG1 = NG7)
1571        //
1572
1573
1574/////// DRK is SKIPPED
1575       
1576//      //read in the DRK data if necessary
1577//      //only one file, assumed to be RAW data
1578//      //
1579//      String fname="",drkStr=""
1580//      drkStr=StringByKey("DRK",prot[6],"=",",")
1581//      if(cmpstr(drkStr,"none") != 0)
1582//              err = ReadHeaderAndData( (pathStr+drkStr) )
1583//              if(err)
1584//                      PathInfo/S catPathName
1585//                      Abort "reduction sequence aborted"
1586//              endif
1587//              err = V_Raw_to_Work_NoNorm("DRK")
1588//      endif
1589
1590        //dispatch to the proper "mode" of Correct()
1591//      V_Dispatch_to_Correct(bgdStr,empStr,drkStr)
1592        V_Dispatch_to_Correct(prot[0],prot[1],prot[6])
1593       
1594        if(err)
1595                PathInfo/S catPathName
1596                SetDataFolder root:
1597                Abort "error in Correct, called from executeprotocol, normal cor"
1598        endif
1599        activeType = "COR"
1600
1601// always update - COR will always be generated
1602        V_UpdateDisplayInformation(ActiveType)         
1603
1604
1605//////////////////////////////
1606//  ABSOLUTE SCALE
1607//////////////////////////////
1608
1609        err = V_Proto_ABS_Scale(prot[4],activeType)
1610       
1611        if(err)
1612                SetDataFolder root:
1613                Abort "Error in V_Absolute_Scale(), called from V_ExecuteProtocol"
1614        endif
1615//      activeType = "ABS"
1616
1617
1618//////////////////////////////
1619// MASK
1620//////////////////////////////
1621//
1622// DONE
1623//              x- fill in the "ask" step
1624//  x- none is OK, except if the kill fails for any reason
1625// x- the regular case of the file name specified by the protocol works correctly
1626// x- don't create a null mask if not used, it will handle the error and print out that the mask is missing
1627//
1628//mask data if desired (mask is applied when the data is binned to I(q)) and is
1629//not done explicitly here
1630       
1631        //check for mask
1632        //doesn't change the activeType
1633        if(!skipLoad)
1634
1635                V_Proto_ReadMask(prot[3])
1636        endif
1637       
1638//////////////////////////////
1639// AVERAGING
1640//////////////////////////////
1641
1642        // average/save data as specified
1643        //Parse the keyword=<Value> string as needed, based on AVTYPE
1644       
1645        //average/plot first
1646        String av_type = StringByKey("AVTYPE",prot[5],"=",";")
1647        If(cmpstr(av_type,"none") != 0)
1648                If (cmpstr(av_type,"")==0)              //if the key could not be found... (if "ask" the string)
1649                        //get the averaging parameters from the user, as if the set button was hit in the panel
1650                        V_SetAverageParamsButtonProc("dummy")           //from "ProtocolAsPanel"
1651                        SVAR tempAveStr = root:Packages:NIST:VSANS:Globals:Protocols:gAvgInfoStr
1652                        av_type = StringByKey("AVTYPE",tempAveStr,"=",";")
1653                else
1654                        //there is info in the string, use the protocol
1655                        //set the global keyword-string to prot[5]
1656                        String/G root:Packages:NIST:VSANS:Globals:Protocols:gAvgInfoStr = prot[5]
1657                Endif
1658        Endif
1659
1660
1661        String detGroup = StringByKey("DETGROUP",prot[5],"=",";")               //only for annular, null if not present
1662
1663       
1664//convert the folder to linear scale before averaging, then revert by calling the window hook
1665// (not needed for VSANS, data is always linear scale)
1666
1667//
1668// (DONE)
1669// -x this generates a "Bin Type Not Found" error if reducing only to a 2D level (like for DIV)
1670//              because binTypeStr is null
1671        String binTypeStr = StringByKey("BINTYPE",prot[5],"=",";")
1672        // plotting is not really necessary, and the graph may not be open - so skip for now?
1673        Variable binType
1674        // only get the binning type if user asks for averaging
1675        If(cmpstr(av_type,"none") != 0)
1676                binType = V_BinTypeStr2Num(binTypeStr)
1677                if(binType == 0)
1678                                Abort "Binning mode not found in V_QBinAllPanels() "// when no case matches
1679                endif
1680        endif
1681
1682
1683// identify the collimation type
1684// this will be a string used to determine how the resolution information is to be calculated
1685// and written to the reduced data file
1686//
1687// possible values are:
1688//
1689// pinhole
1690// pinhole_whiteBeam
1691// narrowSlit
1692// narrowSlit_whiteBeam
1693// convergingPinholes
1694//
1695
1696        String collimationStr
1697        collimationStr = V_IdentifyCollimation(activeType)
1698       
1699
1700////////////////////////////////////////
1701// DISPATCH TO AVERAGING
1702/////////////////////////////////////////
1703//
1704// TODO:
1705// -- do I calculate the proper resolution here?, YES, I've already decoded the binning type
1706//   and the averaging type has been specified by the protocol.
1707//
1708// so currently, the resolution is calculated every time that the data is averaged (in VC_fDoBinning_QxQy2D)
1709//
1710// -- if I calculate the resolution here, then the Trimming routines must be updated
1711//    to trim the resolution waves also. This will work for the columns present in
1712//    pinhole resolution, but anything using the matrix method - it won't work - and I'll need
1713//    a different solution
1714//
1715
1716        V_Proto_doAverage(prot[5],av_type,activeType,binType,collimationStr)
1717
1718
1719
1720////////////////////////
1721// PLOT THE DATA
1722////////////////////////
1723
1724        V_Proto_doPlot(prot[5],av_type,activeType,binType,detGroup)
1725       
1726       
1727
1728////////////////////   
1729// SAVE THE DATA
1730////////////////////
1731
1732//
1733// x- how do I get the sample file name?
1734//    local variable samFileLoaded is the file name loaded (contains the extension)
1735//
1736// V_Proto_SaveFile(avgStr,activeType,samFileLoaded,av_type,binType,detGroup,trimBegStr,trimEndStr)
1737
1738        prot[9] = collimationStr
1739        String outputFileName
1740        outputFileName = RemoveEnding(samStr,".nxs.ngv") + "_SL"+num2str(sliceNum)
1741        //? remove the "Events_" from the beginning? some other naming scheme entirely?
1742       
1743        V_Proto_SaveFile(prot[5],activeType,outputFileName,av_type,binType,detGroup,prot[7],prot[8])
1744       
1745//////////////////////////////
1746// DONE WITH THE PROTOCOL
1747////////////////////////////// 
1748       
1749        // reset any global preferences that I had changed
1750        gDoDIVCor = saved_gDoDIVCor
1751       
1752       
1753        Return(0)
1754End
1755
1756
1757
Note: See TracBrowser for help on using the repository browser.