source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/VSANS/V_TubeAdjustments.ipf @ 1049

Last change on this file since 1049 was 1049, checked in by srkline, 5 years ago

added procedures to use the measured values for the 5 slot masks for detector calibration.

added procedures to save detector panels to be later read in for calibration fitting.

File size: 29.4 KB
Line 
1#pragma rtGlobals=3             // Use modern global access method and strict wave access.
2
3//
4// functions for testing and then actually applying the nonlinear corrections to the
5// tube detectors. These routines are for a test bank of 8 tubes (vertical) that were
6// run at a subdivision of 1024. VSANS will be different in practice
7//
8// but the fundamental process is the same, and can be translated into proper functions as needed
9//
10//
11
12
13//
14// TODO
15// -- need a way to generate the known, physical dimensions of the slots
16// Make/O/D/N=5 peak_spacing_mm_ctr
17// peak_spacing_mm_ctr = {-350,-190,0,190,350} (to be filled in with the correct measurements,
18//   possibly different for each panel)
19//
20// -- a 128 point wave "tube_pixel" (=p) is made in V_ArrayToTubes(), and is needed for the WM
21//   procedures to identify the peak positions.
22//
23// -- fit with either gauss or lor function to get non-integer pixel values for the peak locations
24//
25// -- do I fit each individually to "tweak" the located values, or fit all 5 at once with a
26//    custom fit function and guess some good starting values for peak height, location, etc.
27//
28//
29// -- find a way to display all of the results - in a way that can quickly identify any fits
30//    that may be incorrect
31//
32//
33
34
35
36// the main routines are:
37
38//(1)
39//
40// to get from an array to individual tubes
41// V_ArrayToTubes(detector)
42//
43// (not needed) to get from individual tubes to an array
44//      V_Tubes_to_Array()                     
45
46//(2)
47// then to locate all of the peak positions
48//      V_MakeTableForPeaks(numTube,numPeak)           
49//      V_Identify_AllPeaks()
50//              AutoFindPeaksCustom()           // if Identify_AllPeaks  doesn't work -try this, setting the "noise" to 1 and smoothing to 2
51
52// (3) Refine the fitted peak positions
53//
54
55//(4)
56// fit to find all of the quadratic coefficients
57//      MakeTableForFitCoefs(numTube,numCoef)
58//      PlotFit_AllPeaks()
59
60
61//(5)
62// then pick a display method
63//
64//      Make_mm_tubes()
65//      Append_Adjusted_mm()
66//
67//      MakeMatrix_PixCenter()
68//      FillMatrix_Pix_Center(ind)
69//
70//
71// -or- (note that the pack_image wave that is generated here is for display ONLY)
72// --since it is interpolated
73//
74// Interpolate_mm_tubes()
75
76
77// The function most used externally is:
78// V_TubePix_to_mm(c0,c1,c2,pix)
79//
80// which will return the real space distance (in mm?) for a given pixel
81// and the tube's coefficients. The distance is relative to the zero position on the
82// detector (which was defined when the coefficients were determined)
83
84
85
86//
87// (0) -- what I start with:
88// -- a table of the mm spacing of the slots (20 of them)
89// -- masked data from each of the (8) tubes
90// -- the table of slots may need to be corrected for parallax, depending on the geometry of the test
91// ** In the table of slots, pick a slot near the center, and SET that to ZERO. Then all of the other
92//   distances are relative to that zero point. This is a necessary reference point.
93//
94
95// TODO
96// -- need a routine to set up the actual measurements of the slot positions
97//
98//
99// TODO
100// -- the slot positioning is different for the L/R and T/B detectors
101//
102Proc V_SetupSlotDimensions()
103        Make/O/D/N=5 peak_spacing_mm_ctr_TB,peak_spacing_mm_ctr_LR
104        peak_spacing_mm_ctr_TB = {-159.54,-80.17,0,80.17,159.54}
105        peak_spacing_mm_ctr_LR = {-379.4,-189.7,0,189.7,380.2}
106        DoWindow/F Real_mm_Table
107        if(V_Flag == 0)
108                Edit/N=Real_mm_Table peak_spacing_mm_ctr_TB,peak_spacing_mm_ctr_LR
109        endif
110End
111
112
113
114//
115// (1) -- get the individual tubes into an array
116//
117//
118Proc V_Tubes_to_Array()
119        Make/O/D/N=(8,1127) pack
120        edit pack
121        display;appendimage pack
122        pack[0][] = tube1[q]
123        pack[1][] = tube2[q]
124        pack[2][] = tube3[q]
125        pack[3][] = tube4[q]
126        pack[4][] = tube5[q]
127        pack[5][] = tube6[q]
128        pack[6][] = tube7[q]
129        pack[7][] = tube8[q]
130        ModifyImage pack ctab= {*,*,ColdWarm,0}
131End
132
133// or the other way around
134Proc V_ArrayToTubes(wStr)
135        String wStr
136       
137        String/G root:detUsed = wStr
138       
139        Variable ii,numTubes=48
140        String str="tube"
141       
142        Variable dim0,dim1
143        dim0 = DimSize($wStr,0)
144        dim1 = DimSize($wStr,1)
145
146       
147        Make/O/D/N=128 tube_pixel
148        tube_pixel = p
149       
150       
151        ii=0
152        do
153                Make/O/D/N=128 $(str+num2str(ii))
154               
155                if(dim0 == 128)
156                        $(str+num2str(ii)) = $(wStr)[p][ii]
157                else
158                        $(str+num2str(ii)) = $(wStr)[ii][p]
159                endif
160               
161                ii+=1
162        while(ii < numTubes)
163
164End
165
166
167// (2) -- for each of the tubes, find the x-position (in pixels) of each of the (20) peaks
168// -- load the Analysis Package "MultiPeakFit 2"
169//
170// automatically find the peaks (after including MultiPeakFit 2)
171//              AutomaticallyFindPeaks()
172//
173//-- or if having difficulty
174//              AutoFindPeaksCustom()           // try this, setting the "noise" to 1 and smoothing to 2
175//
176// -- if really having difficulty, you can do the "full" MultiPeak Fit
177//
178// -- If (hopefully) using the easy way, the results are in:
179// root:WA_PeakCentersY,root:WA_PeakCentersX
180//
181// -- so to see the results:
182//¥Edit/K=0  root:WA_PeakCentersY,root:WA_PeakCentersX
183//
184// -- then sort the results - they seem to be in no real order...
185//¥Sort WA_PeakCentersX WA_PeakCentersY,WA_PeakCentersX
186//
187Proc V_MakeTableForPeaks(numTube,numPeak)
188        Variable numTube=48,numPeak=5
189       
190        Make/O/D/N=(numPeak,numTube) PeakTableX,PeakTableY              //*2 to store x-location and peak height (y)
191       
192        DoWindow/F Peak_Pixel_Loc
193        if(V_flag == 0)
194                Edit/N=Peak_Pixel_Loc peakTableX
195        endif
196        DoAlert 0, "Load the Package: Analysis->MultiPeak Fitting->MultiPeak Fitting 2"
197End
198
199Proc V_Identify_AllPeaks()
200
201        Variable ii,numTubes=48
202        String str="tube"
203       
204        ii=0
205        do
206                V_Identify_Peaks(str+num2str(ii),ii)
207                ii+=1
208        while(ii < numTubes)
209
210End
211
212Proc V_Identify_Peaks(tubeStr,ind)
213        String tubeStr
214        Variable ind
215       
216        // must use a wave of pixels rather than "calculated" -- if calculated is used it only
217        // returns integer values for the peak locations
218       
219//      AutomaticallyFindPeaks() //-- this is a function that doesn't take any parameters - so
220// I need to pull this from the WM function to call the worker directly
221        Variable pBegin=0, pEnd= numpnts($(tubeStr))-1
222        Variable/C estimates= EstPeakNoiseAndSmfact($(tubeStr),pBegin, pEnd)
223        Variable noiselevel=real(estimates)
224        Variable smoothingFactor=imag(estimates)
225        Variable maxPeaks = 20
226        Variable minPeakPercent = 10
227       
228        AutoFindPeaksWorker($(tubeStr), $("tube_pixel"), pBegin, pEnd, maxPeaks, minPeakPercent, noiseLevel, smoothingFactor)
229// end WM function call
230
231        Sort WA_PeakCentersX WA_PeakCentersY,WA_PeakCentersX
232       
233        peakTableX[][ind] = WA_PeakCentersX[p]          // the peak position
234        peakTableY[][ind] = WA_PeakCentersY[p]          // the peak height
235       
236End
237
238
239
240
241// ADD
242// a step to refine the peak positioning - currently an integer value
243//  fit with a gauss or lorentzian
244
245// CurveFit/M=2/W=0/TBOX=(0x310) lor, tube47[29,53]/X=tube_pixel[29,53]/D
246
247//CurveFit/M=2/W=0 lor, tube47[29,53]/X=tube_pixel[29,53]/D
248//fit_tube47= W_coef[0]+W_coef[1]/((x-W_coef[2])^2+W_coef[3])
249//W_coef={-20.37,876.94,40.078,0.5201}
250//W_sigma={6.52,47.3,0.0241,0.0308}
251
252Proc V_MakeTableForRefinedFit(numTube,numPeak)
253        Variable numTube=48,numPeak=5
254       
255        Make/O/D/N=(numPeak,numTube) position_refined,position_refined_err              //
256       
257        DoWindow/F Refined_Positions
258        if(V_flag == 0)
259                Edit/N=Refined_Positions position_refined
260        endif
261       
262End
263
264Proc V_Refine_All_PeakPos()
265
266        Variable ii,numTubes=48
267       
268        ii=0
269        do
270                V_Refine_PeakPos(ii)
271                ii+=1
272        while(ii<numTubes)
273
274End
275
276
277//CurveFit/M=2/W=0 lor, tube47[29,53]/X=tube_pixel[29,53]/D
278//fit_tube47= W_coef[0]+W_coef[1]/((x-W_coef[2])^2+W_coef[3])
279
280Proc V_Refine_PeakPos(ind)
281        Variable ind
282       
283// TODO
284// -- hard-wired for 5 peaks
285
286        Variable ii,lo,hi
287       
288       
289        ii=0
290        do
291       
292                if(ii==0)
293                // 1st peak
294                // define fitting range pixels (integer)
295                        lo = 0
296                else
297                        lo = trunc(0.5*(peakTableX[ii-1][ind] + peakTableX[ii][ind]))
298                endif
299               
300                if(ii==4)
301                        hi = numpnts(tube_pixel)-1
302                else
303                        hi = trunc(0.5*(peakTableX[ii][ind] + peakTableX[ii+1][ind]))
304                endif
305               
306                // do I need initial guesses?
307                CurveFit/M=0/W=2 lor, $("tube"+num2str(ind))[lo,hi]/X=tube_pixel[lo,hi]/D
308               
309                position_refined[ii][ind] = W_coef[2]
310                position_refined_err[ii][ind] = W_sigma[2]
311
312                ii += 1
313
314        while(ii < 5)
315       
316End
317
318
319
320
321
322// -- save a copy of the root:WA_PeakCentersY,root:WA_PeakCentersX values
323//    for later in case the fitting failed, then you can go back and re-do
324//
325// -- then plot:
326//
327//      Display peak_spacing_mm_ctr vs WA_PeakCentersX
328//
329//      Then do a "QuickFit" of the peak position to the data using a polynomial of order 3 (= quadratic)
330//
331// result is in W_coef, W_sigma
332//
333// -- an example of the "quickFit" command is below, so it can be programmed rather than the menu every time
334//¥Display peak_spacing_mm_ctr vs WA_PeakCentersX3
335//¥CurveFit/M=2/W=0/TBOX=(0x310) poly 3, peak_spacing_mm_ctr/X=WA_PeakCentersX3/D
336//  fit_peak_spacing_mm_ctr= poly(W_coef,x)
337//  W_coef={-571.42,1.1135,-4.2444e-05}
338//  V_chisq= 8.5841;V_npnts= 20;V_numNaNs= 0;V_numINFs= 0;
339//  V_startRow= 0;V_endRow= 19;
340//  W_sigma={0.595,0.00246,2.15e-06}
341//  Coefficient values ± one standard deviation
342//      K0      =-571.42 ± 0.595
343//      K1      =1.1135 ± 0.00246
344//      K2      =-4.2444e-05 ± 2.15e-06
345//
346//
347//
348// for (8) tubes, keep all of the fit coefficients
349//
350//¥make/O/D/N=(3,8) fit_coef
351//¥edit fit_coef
352//¥make/O/D/N=(3,8) fit_sigma
353//¥edit fit_sigma
354//
355// -- copy and paste in the W_coef and W_sigma values (or by a command)
356//
357
358
359Proc V_MakeTableForFitCoefs(numTube,numCoef)
360        Variable numTube=48,numCoef=3
361       
362        Make/O/D/N=(numTube,numCoef) TubeCoefTable,TubeSigmaTable               //
363       
364        DoWindow/F Quad_Coefficients
365        if(V_flag == 0)
366                Edit/N=Quad_Coefficients TubeCoefTable
367        endif
368
369        String detUsed = root:detUsed
370       
371        if(strsearch(detUsed,"L",0) >= 0 || strsearch(detUsed,"R",0) >= 0)
372                Duplicate/O     peak_spacing_mm_ctr_LR, peak_spacing_mm_ctr
373                DoAlert 0,"Using peak spacing for L/R"
374        else
375                Duplicate/O     peak_spacing_mm_ctr_TB, peak_spacing_mm_ctr
376                DoAlert 0,"Using peak spacing for T/B"
377        endif
378End
379
380Proc V_PlotFit_AllPeakPosition()
381
382        Variable ii,numTubes=48
383       
384        ii=0
385        do
386                V_PlotFit_PeakPosition(ii)
387                ii+=1
388        while(ii<numTubes)
389
390End
391
392Proc V_PlotFit_PeakPosition(ind)
393        Variable ind
394       
395        Duplicate/O WA_PeakCentersX, tmpX
396       
397//      tmpX = peakTableX[p][ind]
398        tmpX = position_refined[p][ind]
399//      Display peak_spacing_mm_ctr vs tmpX
400       
401//      CurveFit/M=2/W=0/TBOX=(0x310) poly 3, peak_spacing_mm_ctr/X=tmpX/D
402        CurveFit/M=0/W=2 poly 3, peak_spacing_mm_ctr/X=tmpX/D
403       
404        TubeCoefTable[ind][] = W_coef[q]
405        TubeSigmaTable[ind][] = W_sigma[q]
406       
407End
408
409
410
411
412
413//¥Duplicate tube1 tube1_mm
414//¥tube1_mm = V_TubePix_to_mm(fit_coef[0][0],fit_coef[1][0],fit_coef[2][0],p)
415
416
417
418
419////////
420// then there are various display options:
421
422// adjust the center (pixel) of the tube:
423// - measCtr is the pixel location of the DEFINED "zero" peak
424// nominal Ctr is the pixel number of this DEFINED zer0 position, nominally nPix/2-1
425//
426// ( be sure to pick better names, and use a loop...)
427//      adj_tube = raw_tube[p+(measCtr-nominalCtr)]
428//
429// then fill and display a new matrix. The center will be reasonably well aligned, and will
430// get worse towards the ends of the tubes
431// (this may be the "preferred" way of displaying the raw data if the centers are far off)
432// -- this also may be what I need to start with to fit the data to locate the beam center.
433
434
435// I can also display the fully corrected tubes, where the y-axis is now in real-space mm
436// rather than arbitrary pixels. The x-axis is still tube nubmer.
437// -- do this with the procedure"
438//   Append_Adjusted_mm()               // name may change...
439//
440// -- the point of the appending is that it allows each tube to be plotted on an image plot
441// with its own y-axis. Every one will be different and will be non-linear. These conditions
442// BOTH prevent using any of the "normal" image plotting or manipulation routines.
443// - the gist is below:
444//
445//      duplicate tube1_mm adjusted_mm_edge
446//      InsertPoints 0,1, adjusted_mm_edge
447//      // be sure to use the correct set of coefficients
448//      adjusted_mm_edge[0] = V_TubePix_to_mm(fit_coef[0][0],fit_coef[1][0],fit_coef[2][0],-1)
449//     
450//      Display;AppendImage adjusted_pack vs {*,adjusted_mm_edge}
451
452
453Proc V_Make_mm_tubes()
454
455        Variable ii,numTubes=8
456       
457        ii=1
458        do
459                Duplicate $("tube"+num2str(ii)) $("tube"+num2str(ii)+"_mm")
460                $("tube"+num2str(ii)+"_mm") = V_TubePix_to_mm(TubeCoefTable[ii-1][0],TubeCoefTable[ii-1][1],TubeCoefTable[ii-1][2],p)
461                ii+=1
462        while(ii<=numTubes)
463       
464End
465
466
467Proc V_Append_Adjusted_mm()
468
469// a blank base image
470        Duplicate/O pack junk
471        junk=0
472        SetScale/I y -600,600,"", junk          // -600,600 is tooo large and not general
473        Display;Appendimage junk
474
475        Variable ii
476       
477        ii=1
478        do
479                make/O/D/N=(1,1127) $("tube"+num2str(ii)+"_mm_mat")=0   
480       
481                $("tube"+num2str(ii)+"_mm_mat")[0][] = $("tube"+num2str(ii))
482                SetScale/I x (ii-1),ii,"", $("tube"+num2str(ii)+"_mm_mat")              //builds up the x-axis
483               
484                duplicate/O $("tube"+num2str(ii)+"_mm") $("edge"+num2str(ii)+"_mm")
485                InsertPoints 0,1, $("edge"+num2str(ii)+"_mm")           //needs to be one point longer
486        // be sure to use the correct set of coefficients
487                $("edge"+num2str(ii)+"_mm")[0] = V_TubePix_to_mm(TubeCoefTable[0][0],TubeCoefTable[0][1],TubeCoefTable[0][2],-1)
488       
489                AppendImage $("tube"+num2str(ii)+"_mm_mat") vs {*,$("edge"+num2str(ii)+"_mm")}
490                ModifyImage $("tube"+num2str(ii)+"_mm_mat") ctab= {*,*,ColdWarm,0}
491       
492                ii+=1
493        while(ii < 9)
494       
495end
496
497
498
499////////////////////////////////
500
501Proc V_MakeMatrix_PixCenter()
502        Duplicate/O pack pack_centered
503       
504        Variable ii,numTubes=8
505       
506        ii=1
507        do
508                V_FillMatrix_Pix_Center(ii)
509                ii+=1
510        while(ii<=numTubes)
511       
512        Display;AppendImage pack_centered
513        ModifyImage pack_centered ctab= {*,*,ColdWarm,0}
514
515end
516
517//
518// this fills a matrix with the tubes center aligned ONLY, with the y-axis in pixels
519//
520// adj_tube = raw_tube[p+(measCtr-nominalCtr)]
521// finds the center automatically from the tubeN_mm wave, where it crosses zero
522//
523// Tube #1 is the "base" ans others are shifted to match that one's "zero"
524//
525// FindRoots/P=W_coef           can also be used to find the roots (but which one?)
526//
527Function V_FillMatrix_Pix_Center(ind)
528        Variable ind
529       
530        Wave adj=root:pack_centered
531        Wave tube1_mm = $("root:tube1_mm")
532        Wave tube = $("root:tube"+num2str(ind))
533        wave tube_mm = $("root:tube"+num2str(ind)+"_mm")
534
535        Variable base,shift,ii,num,pt
536       
537        num=numpnts(tube)
538       
539        FindLevel tube1_mm 0
540        base = round(V_LevelX)
541       
542       
543        FindLevel tube_mm 0
544        shift = round(V_LevelX)
545       
546        for(ii=0;ii<num;ii+=1)
547                pt = ii + (shift-base)
548                if(pt >= 0 && pt < num)
549                        adj[ind-1][ii] = tube[pt]
550                endif
551        endfor
552       
553        return(0)
554End
555
556
557// this fills a matrix with the tubes center aligned ONLY, with the y-axis in mm
558// -- there seems to be little reason to do this --
559// -- either keep pixels and align centers
560// -- OR -- use mm and append each tube with its own y-axis
561//
562Function V_FillAdjusted(ind)
563        Variable ind
564       
565        Wave adj=root:adjusted_pack
566        Wave tube1_mm
567        Wave tube = $("root:tube"+num2str(ind))
568        wave tube_mm = $("root:tube"+num2str(ind)+"_mm")
569
570        Variable base,shift,ii,num,pt
571       
572        num=numpnts(tube1_mm)
573       
574        FindLevel tube1_mm 0
575        base = round(V_LevelX)
576       
577       
578        FindLevel tube_mm 0
579        shift = round(V_LevelX)
580       
581        for(ii=0;ii<num;ii+=1)
582                pt = ii + (shift-base)
583                if(pt >= 0 && pt < num)
584                        adj[ind-1][ii] = tube[pt]
585                endif
586        endfor
587       
588        return(0)
589End
590
591
592// c0,c1,c2,pix
593// c0-c2 are the fit coefficients
594// pix is the test pixel
595//
596// returns the distance in mm (relative to ctr pixel)
597// ctr is the center pixel, as defined when fitting to quadratic
598//
599Function V_TubePix_to_mm(c0,c1,c2,pix)
600        Variable c0,c1,c2,pix
601       
602        Variable dist
603        dist = c0 + c1*pix + c2*pix*pix
604       
605        return(dist)
606End
607
608////
609
610
611
612// set the (linear) range of the y-axis of the matrix to be the
613// range of the 1st tube. This is completely arbitrary
614//
615Proc V_Interpolate_mm_tubes()
616
617        Duplicate/O pack pack_image
618
619        Variable ii,numTubes=8
620        Variable p1,p2
621        p1 = tube1_mm[0]
622        p2 = tube1_mm[numpnts(tube1_mm)-1]
623       
624        SetScale/I y p1,p2,"", pack_image
625       
626        // then make a temporary 1D wave to help with the interpolation
627        Duplicate/O tube1_mm lin_mm,lin_val
628        SetScale/I x p1,p2,"", lin_mm
629        lin_mm = x                      //fill with the linear mm spacing
630        lin_val=0
631       
632        ii=1
633        do
634                lin_val = interp(lin_mm, $("tube"+num2str(ii)+"_mm"), $("tube"+num2str(ii)))
635                pack_image[ii-1][] = lin_val[q]
636               
637                ii+=1
638        while(ii<=numTubes)
639       
640        display;appendimage pack_image
641        ModifyImage pack_image ctab= {*,*,ColdWarm,0}
642       
643End
644
645
646
647
648
649
650
651
652
653
654
655
656
657// this doesn't work - the interpolation step doesn't do what I want
658// and the plot of the triplet with f(z) for color doesn't fill space like I want
659Proc V_AnotherExample()
660
661        Concatenate/O/NP {tube1_mm,tube2_mm,tube3_mm,tube4_mm,tube5_mm,tube6_mm,tube7_mm,tube8_mm},cat_mm
662        Concatenate/O/NP {tube1,tube2,tube3,tube4,tube5,tube6,tube7,tube8},cat_tubes
663        Duplicate/O cat_mm,cat_num
664        Variable num=1127
665        cat_num[0,num-1]=1
666        cat_num[num,2*num-1]=2
667        cat_num[2*num,3*num-1]=3
668        cat_num[3*num,4*num-1]=4
669        cat_num[4*num,5*num-1]=5
670        cat_num[5*num,6*num-1]=6
671        cat_num[6*num,7*num-1]=7
672        cat_num[7*num,8*num-1]=8
673
674        Display cat_mm vs cat_num
675        ModifyGraph mode=3,marker=9
676        ModifyGraph zColor(cat_mm)={cat_tubes,*,*,ColdWarm,0}
677
678        Concatenate/O {cat_num,cat_mm,cat_tubes}, tripletWave
679        ImageInterpolate Kriging tripletWave
680        AppendImage M_InterpolatedImage
681
682//      Make/O/N=20 xWave=enoise(4),yWave=enoise(5),zWave=enoise(6)  // Random points
683//      Display yWave vs xWave
684//      ModifyGraph mode=3,marker=19
685//      ModifyGraph zColor(yWave)={zWave,*,*,Rainbow,0}
686//
687//      Concatenate/O {xWave,yWave,zWave}, tripletWave
688//      ImageInterpolate/S={-5,0.1,5,-5,0.1,5} voronoi tripletWave
689//      AppendImage M_InterpolatedImage
690
691end
692
693// this desn't work either...
694// (same y-axis for the entire image, which is not the case for the tubes)
695//
696// from the WM help file:
697// Plotting a 2D Z Wave With 1D X and Y Center Data
698//
699Function V_MakeEdgesWave(centers, edgesWave)
700        Wave centers    // Input
701        Wave edgesWave  // Receives output
702       
703        Variable N=numpnts(centers)
704        Redimension/N=(N+1) edgesWave
705
706        edgesWave[0]=centers[0]-0.5*(centers[1]-centers[0])
707        edgesWave[N]=centers[N-1]+0.5*(centers[N-1]-centers[N-2])
708        edgesWave[1,N-1]=centers[p]-0.5*(centers[p]-centers[p-1])
709End
710
711//This function demonstrates the use of MakeEdgesWave:
712Function V_DemoPlotXYZAsImage()
713        Make/O mat={{0,1,2},{2,3,4},{3,4,5}}    // Matrix containing Z values
714        Make/O centersX = {1, 2.5, 5}           // X centers wave
715        Make/O centersY = {300, 400, 600}               // Y centers wave
716        Make/O edgesX; V_MakeEdgesWave(centersX, edgesX)        // Create X edges wave
717        Make/O edgesY; V_MakeEdgesWave(centersY, edgesY)        // Create Y edges wave
718        Display; AppendImage mat vs {edgesX,edgesY}
719End
720
721
722
723////////////////////////////
724
725Proc V_TubeCoefPanel() : Panel
726        PauseUpdate; Silent 1           // building window...
727        NewPanel /W=(973,45,1156,535)/K=1
728        DoWindow/C V_TubeCoefPanel
729//      ShowTools/A
730
731        SetDrawLayer UserBack
732        SetDrawEnv fsize= 14,fstyle= 1
733        DrawText 5,58,"(1)"
734        SetDrawEnv fsize= 14,fstyle= 1
735        DrawText 5,108,"(2)"
736        SetDrawEnv fsize= 14,fstyle= 1
737        DrawText 5,158,"(3)"
738        SetDrawEnv fsize= 14,fstyle= 1
739        DrawText 5,208,"(4)"
740        SetDrawEnv fsize= 14,fstyle= 1
741        DrawText 5,258,"(5)"
742        SetDrawEnv fsize= 14,fstyle= 1
743        DrawText 5,308,"(6)"
744        SetDrawEnv fsize= 14,fstyle= 1
745        DrawText 5,358,"(7)"
746        SetDrawEnv fsize= 14,fstyle= 1
747        DrawText 5,408,"(8)"
748        SetDrawEnv fsize= 14,fstyle= 1
749        DrawText 5,458,"(9)"
750                       
751        Button button_0,pos={30.00,40.00},size={120.00,20.00},proc=V_Setup_MasksButton,title="Setup"
752        Button button_1,pos={30.00,90.00},size={120.00,20.00},proc=V_ArrayToTubesButton,title="Array to Tubes"
753        Button button_2,pos={30.00,140.00},size={120.00,20.00},proc=V_TableForPeaksButton,title="Table for Peaks"
754        Button button_3,pos={30.00,190.00},size={120.00,20.00},proc=V_IdentifyPeaksButton,title="Identify Peaks"
755        Button button_4,pos={30.00,240.00},size={120.00,20.00},proc=V_RefineTableButton,title="Refine Peak Table"
756        Button button_5,pos={30.00,290.00},size={120.00,20.00},proc=V_RefinePeaksButton,title="Refine Peaks"
757
758        Button button_6,pos={30.00,340.00},size={120.00,20.00},proc=V_QuadFitTableButton,title="Table for Quad"
759        Button button_7,pos={30.00,390.00},size={120.00,20.00},proc=V_QuadFitButton,title="Fit to Quad"
760        Button button_8,pos={30.00,440},size={120.00,20.00},proc=V_PeakPlotButton,title="Plot Peaks"
761       
762EndMacro
763
764
765Function V_PeakPlotButton(ba) : ButtonControl
766        STRUCT WMButtonAction &ba
767
768        switch( ba.eventCode )
769                case 2: // mouse up
770                        // click code here
771                        Execute "V_OpenPeakResultsGraph()"
772                        break
773                case -1: // control being killed
774                        break
775        endswitch
776
777        return 0
778End
779
780
781Function V_TableForPeaksButton(ba) : ButtonControl
782        STRUCT WMButtonAction &ba
783
784        switch( ba.eventCode )
785                case 2: // mouse up
786                        // click code here
787                        Execute "V_MakeTableForPeaks()"
788                        break
789                case -1: // control being killed
790                        break
791        endswitch
792
793        return 0
794End
795
796
797Function V_IdentifyPeaksButton(ba) : ButtonControl
798        STRUCT WMButtonAction &ba
799
800        switch( ba.eventCode )
801                case 2: // mouse up
802                        // click code here
803                        Execute "V_Identify_AllPeaks()"
804                        break
805                case -1: // control being killed
806                        break
807        endswitch
808
809        return 0
810End
811
812Function V_RefineTableButton(ba) : ButtonControl
813        STRUCT WMButtonAction &ba
814
815        switch( ba.eventCode )
816                case 2: // mouse up
817                        // click code here
818                        Execute "V_MakeTableForRefinedFit()"
819                        break
820                case -1: // control being killed
821                        break
822        endswitch
823
824        return 0
825End
826
827Function V_RefinePeaksButton(ba) : ButtonControl
828        STRUCT WMButtonAction &ba
829
830        switch( ba.eventCode )
831                case 2: // mouse up
832                        // click code here
833                        Execute "V_Refine_All_PeakPos()"
834                        break
835                case -1: // control being killed
836                        break
837        endswitch
838
839        return 0
840End
841
842Function V_QuadFitTableButton(ba) : ButtonControl
843        STRUCT WMButtonAction &ba
844
845        switch( ba.eventCode )
846                case 2: // mouse up
847                        // click code here
848                        Execute "V_MakeTableForFitCoefs()"
849                        break
850                case -1: // control being killed
851                        break
852        endswitch
853
854        return 0
855End
856
857Function V_QuadFitButton(ba) : ButtonControl
858        STRUCT WMButtonAction &ba
859
860        switch( ba.eventCode )
861                case 2: // mouse up
862                        // click code here
863                        Execute "V_PlotFit_AllPeakPosition()"
864                        break
865                case -1: // control being killed
866                        break
867        endswitch
868
869        return 0
870End
871
872
873
874Function V_Setup_MasksButton(ba) : ButtonControl
875        STRUCT WMButtonAction &ba
876
877        switch( ba.eventCode )
878                case 2: // mouse up
879                        // click code here
880                        Execute "V_SetupSlotDimensions()"
881                        break
882                case -1: // control being killed
883                        break
884        endswitch
885
886        return 0
887End
888
889
890
891Function V_ArrayToTubesButton(ba) : ButtonControl
892        STRUCT WMButtonAction &ba
893
894        switch( ba.eventCode )
895                case 2: // mouse up
896                        // click code here
897                        Execute "V_ArrayToTubes()"
898                        break
899                case -1: // control being killed
900                        break
901        endswitch
902
903        return 0
904End
905
906
907///////////////////////////
908
909
910Window Gizmo_refinedPositions() : GizmoPlot
911        PauseUpdate; Silent 1           // building window...
912        // Building Gizmo 7 window...
913        NewGizmo/W=(232,448,747,908)
914        ModifyGizmo startRecMacro=700
915        ModifyGizmo scalingOption=63
916        AppendToGizmo Surface=root:position_refined,name=surface0
917        ModifyGizmo ModifyObject=surface0,objectType=surface,property={ srcMode,0}
918        ModifyGizmo ModifyObject=surface0,objectType=surface,property={ surfaceCTab,Rainbow}
919        AppendToGizmo Axes=boxAxes,name=axes0
920        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={0,axisRange,-1,-1,-1,1,-1,-1}
921        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={1,axisRange,-1,-1,-1,-1,1,-1}
922        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={2,axisRange,-1,-1,-1,-1,-1,1}
923        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={3,axisRange,-1,1,-1,-1,1,1}
924        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={4,axisRange,1,1,-1,1,1,1}
925        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={5,axisRange,1,-1,-1,1,-1,1}
926        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={6,axisRange,-1,-1,1,-1,1,1}
927        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={7,axisRange,1,-1,1,1,1,1}
928        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={8,axisRange,1,-1,-1,1,1,-1}
929        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={9,axisRange,-1,1,-1,1,1,-1}
930        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={10,axisRange,-1,1,1,1,1,1}
931        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={11,axisRange,-1,-1,1,1,-1,1}
932        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={-1,axisScalingMode,1}
933        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={-1,axisColor,0,0,0,1}
934        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={0,ticks,2}
935        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={1,ticks,2}
936        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={2,ticks,2}
937        ModifyGizmo modifyObject=axes0,objectType=Axes,property={-1,Clipped,0}
938        ModifyGizmo setDisplayList=0, object=surface0
939        ModifyGizmo setDisplayList=1, object=axes0
940        ModifyGizmo autoscaling=1
941        ModifyGizmo currentGroupObject=""
942        ModifyGizmo showInfo
943        ModifyGizmo infoWindow={651,303,1468,602}
944        ModifyGizmo endRecMacro
945        ModifyGizmo SETQUATERNION={0.573113,-0.115160,-0.275160,0.763255}
946EndMacro
947
948Window Gizmo_DetPanel() : GizmoPlot
949        PauseUpdate; Silent 1           // building window...
950        // Building Gizmo 7 window...
951        NewGizmo/W=(96,290,611,750)
952        ModifyGizmo startRecMacro=700
953        ModifyGizmo scalingOption=63
954        AppendToGizmo Surface=root:slices_L,name=surface0
955        ModifyGizmo ModifyObject=surface0,objectType=surface,property={ srcMode,0}
956        ModifyGizmo ModifyObject=surface0,objectType=surface,property={ surfaceCTab,ColdWarm}
957        AppendToGizmo Axes=boxAxes,name=axes0
958        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={0,axisRange,-1,-1,-1,1,-1,-1}
959        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={1,axisRange,-1,-1,-1,-1,1,-1}
960        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={2,axisRange,-1,-1,-1,-1,-1,1}
961        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={3,axisRange,-1,1,-1,-1,1,1}
962        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={4,axisRange,1,1,-1,1,1,1}
963        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={5,axisRange,1,-1,-1,1,-1,1}
964        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={6,axisRange,-1,-1,1,-1,1,1}
965        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={7,axisRange,1,-1,1,1,1,1}
966        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={8,axisRange,1,-1,-1,1,1,-1}
967        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={9,axisRange,-1,1,-1,1,1,-1}
968        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={10,axisRange,-1,1,1,1,1,1}
969        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={11,axisRange,-1,-1,1,1,-1,1}
970        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={-1,axisScalingMode,1}
971        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={-1,axisColor,0,0,0,1}
972        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={0,ticks,3}
973        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={1,ticks,3}
974        ModifyGizmo ModifyObject=axes0,objectType=Axes,property={2,ticks,3}
975        ModifyGizmo modifyObject=axes0,objectType=Axes,property={-1,Clipped,0}
976        AppendToGizmo Surface=root:position_refined,name=surface1
977        ModifyGizmo ModifyObject=surface1,objectType=surface,property={ fillMode,4}
978        ModifyGizmo ModifyObject=surface1,objectType=surface,property={ srcMode,0}
979        ModifyGizmo ModifyObject=surface1,objectType=surface,property={ surfaceCTab,Rainbow}
980        ModifyGizmo setDisplayList=0, object=axes0
981        ModifyGizmo setDisplayList=1, object=surface0
982        ModifyGizmo autoscaling=1
983        ModifyGizmo currentGroupObject=""
984        ModifyGizmo showInfo
985        ModifyGizmo infoWindow={550,23,1367,322}
986        ModifyGizmo endRecMacro
987        ModifyGizmo SETQUATERNION={0.499484,-0.278571,-0.448869,0.686609}
988EndMacro
989
990
991////////////////////////////////////
992//
993// An easy way to see the fit results to check if the peak locations all make sense.
994//
995Proc V_OpenPeakResultsGraph()
996
997        DoWindow/F V_PeakResultsGraph
998        if(V_flag == 0)
999                Make/O/D/N=5 tmpPeak,dummyLevel
1000                Make/O/D/N=128 tmpTube
1001               
1002                tmpPeak = position_refined[p][0]
1003                dummyLevel = WaveMax(tube0)
1004                tmpTube = tube0
1005               
1006                V_PeakResultsGraph()
1007        endif
1008
1009End
1010
1011Window V_PeakResultsGraph() : Graph
1012        PauseUpdate; Silent 1           // building window...
1013        Display /W=(750,45,1161,376)/K=1 tmpTube vs tube_pixel
1014       
1015        ControlBar 50
1016       
1017       
1018        AppendToGraph dummyLevel vs tmpPeak
1019        ModifyGraph mode(dummyLevel)=3
1020        ModifyGraph marker(dummyLevel)=19
1021        ModifyGraph rgb(dummyLevel)=(1,16019,65535)
1022       
1023        SetVariable setvar0,pos={10.00,10.00},size={120.00,14.00},proc=V_TubePeakSetVarProc,title="Tube"
1024        SetVariable setvar0,limits={0,47,1},value= _NUM:0
1025       
1026        Label left "Counts"
1027        Label bottom "Pixel Number"
1028EndMacro
1029
1030
1031Function V_TubePeakSetVarProc(sva) : SetVariableControl
1032        STRUCT WMSetVariableAction &sva
1033
1034        switch( sva.eventCode )
1035                case 1: // mouse up
1036                case 2: // Enter key
1037                case 3: // Live update
1038                        Variable dval = sva.dval
1039                        String sval = sva.sval
1040                       
1041                        Wave tmpPeak = tmpPeak
1042                        Wave dummyLevel = dummyLevel
1043                        Wave tmpTube = tmpTube
1044                       
1045                        Wave pos_ref = position_refined
1046                        Wave tube = $("tube"+num2str(dval))
1047                       
1048                        tmpPeak = pos_ref[p][dval]
1049                        dummyLevel = WaveMax(tube)
1050                        tmpTube = tube
1051               
1052                        break
1053                case -1: // control being killed
1054                        break
1055        endswitch
1056
1057        return 0
1058End
1059
1060////////////////////////////////////
1061//
1062// TODO
1063// -- document the "simple" save of the detector panels for import and subsequent fitting.
1064//
1065// takes the data from RAW, by default. This is OK, since even though whatever is in the calibration data
1066// of the file is used when loading into RAW, it is only used for the calculation of q. The actual data
1067// array is unchanged. Alternatively, the data could be pulled from the RawVSANS folder after a
1068// file catalog operation
1069
1070Macro V_CopyDetectorsToRoot()
1071
1072        Duplicate/O root:Packages:NIST:VSANS:RAW:entry:instrument:detector_B:data data_B
1073
1074        Duplicate/O root:Packages:NIST:VSANS:RAW:entry:instrument:detector_ML:data data_ML
1075        Duplicate/O root:Packages:NIST:VSANS:RAW:entry:instrument:detector_MR:data data_MR
1076        Duplicate/O root:Packages:NIST:VSANS:RAW:entry:instrument:detector_MT:data data_MT
1077        Duplicate/O root:Packages:NIST:VSANS:RAW:entry:instrument:detector_MB:data data_MB
1078
1079        Duplicate/O root:Packages:NIST:VSANS:RAW:entry:instrument:detector_FL:data data_FL
1080        Duplicate/O root:Packages:NIST:VSANS:RAW:entry:instrument:detector_FR:data data_FR
1081        Duplicate/O root:Packages:NIST:VSANS:RAW:entry:instrument:detector_FT:data data_FT
1082        Duplicate/O root:Packages:NIST:VSANS:RAW:entry:instrument:detector_FB:data data_FB
1083       
1084End
1085
1086Macro V_SaveDetectorsITX()
1087// binary save makes each wave an individual file. Igor text groups them all into one file.
1088//      Save/C data_B,data_FB,data_FL,data_FR,data_FT,data_MB,data_ML,data_MR,data_MT
1089        Save/T/M="\r\n" data_B,data_FB,data_FL,data_FR,data_FT,data_MB,data_ML,data_MR,data_MT as "data_B++.itx"
1090
1091End
Note: See TracBrowser for help on using the repository browser.