1 | #pragma rtGlobals=1 // Use modern global access method. |
---|
2 | |
---|
3 | |
---|
4 | // FFT and DebyeSphere calculations are now properly normalized to the conditions of: |
---|
5 | // deltaRho = 1e-6 (set as a global) |
---|
6 | // volume fraction = occupied fraction |
---|
7 | // |
---|
8 | |
---|
9 | // another thing to add - for the FFT when taking a slice. To test the rotational average, set up a loop |
---|
10 | // that does the FFT, rotates, sums the intensity (the q's are the same), and reports the average. May need to |
---|
11 | // rotate a large number of times to get a "real" average |
---|
12 | // |
---|
13 | // |
---|
14 | // -- Feb 2011 |
---|
15 | // You can use N=512. The FFT takes about 140 s (first time), then 75s after that. |
---|
16 | // The size of the whole experiment must be enormous. |
---|
17 | // 512^2 = 134 MB for the byte matrix. |
---|
18 | // (512^3)/2*4 = 268 MB for the FFT result |
---|
19 | // |
---|
20 | // Function Interpolate2DSliceToData(folderStr) |
---|
21 | // -- this function takes the 2D slice and interpolates the q-values to the experimental data for comparison (or a fit!) |
---|
22 | // |
---|
23 | Proc DoFFT() |
---|
24 | |
---|
25 | Variable t0=ticks,t1=ticks |
---|
26 | |
---|
27 | fDoFFT() |
---|
28 | // Print "FFT time (s) = ",(ticks - t1)/60.15 |
---|
29 | |
---|
30 | t1=ticks |
---|
31 | fDoCorrection(dmat) // dmat will exist, and be complex on input |
---|
32 | // Print "Cube correction time (s) = ",(ticks - t1)/60.15 |
---|
33 | |
---|
34 | t1 = ticks |
---|
35 | fGetMagnitude(tmp) //complex on input, returns as real-valued |
---|
36 | // Print "Magnitude Calculation time (s) = ",(ticks - t1)/60.15 |
---|
37 | |
---|
38 | t1=ticks |
---|
39 | fDoBinning(dmat,0) // dmat is purely real when the binning is done, do not normalize result |
---|
40 | // Print "Binning time (s) = ",(ticks - t1)/60.15 |
---|
41 | |
---|
42 | Print "Total FFT time (s) = ",(ticks - t0)/60.15 |
---|
43 | Print " " |
---|
44 | |
---|
45 | //normalize the data |
---|
46 | Variable Tscale=root:FFT_T |
---|
47 | |
---|
48 | Variable delRho,vol,nx,phi |
---|
49 | |
---|
50 | delRho = root:FFT_delRho //simply the units of SLD, not the absolute value |
---|
51 | |
---|
52 | // WaveStats/Q mat |
---|
53 | // must do this to get the number of non-zero voxels |
---|
54 | Variable FFT_N = root:FFT_N |
---|
55 | // nx = NonZeroValues(mat) |
---|
56 | // phi = nx/FFT_N^3 |
---|
57 | // vol = nx*(Tscale)^3 |
---|
58 | |
---|
59 | // iBin *= phi |
---|
60 | // iBin /= vol |
---|
61 | |
---|
62 | // iBin *= delRho*delRho |
---|
63 | // iBin *= 1e8 |
---|
64 | // |
---|
65 | // iBin *= (Tscale)^6 //this puts units on the FFT(magnitude), Vol^2 = T^6 |
---|
66 | |
---|
67 | |
---|
68 | // iBin *= phi/vol*(1e-6)^2*(1e8)*T^6 |
---|
69 | // is equivalent to |
---|
70 | // iBin *= (T/N)^3 * (1e-6)^2*(1e8) |
---|
71 | |
---|
72 | iBin *= delRho*delRho |
---|
73 | iBin *= 1e8 |
---|
74 | iBin *= (Tscale/FFT_N)^3 |
---|
75 | |
---|
76 | end |
---|
77 | |
---|
78 | // for future speedups... |
---|
79 | // 1/2 the time is spent on the Duplicate and redimension step |
---|
80 | // other 1/2 is spent on the FFT |
---|
81 | Function fDoFFT() |
---|
82 | |
---|
83 | Wave mat=mat |
---|
84 | Variable t0,t1 |
---|
85 | |
---|
86 | // t1 = ticks |
---|
87 | Duplicate/O mat dmat |
---|
88 | Redimension/S dmat //need single or double precision for FFT |
---|
89 | //use single precision to use 1/2 memory space - since I'm averaging over the FFT result |
---|
90 | // I don't need double precision.- the results are identical |
---|
91 | // print (ticks-t1)/60.15 |
---|
92 | |
---|
93 | //Set the proper real-space dimensions for the cubes |
---|
94 | // |
---|
95 | NVAR Tscale=root:FFT_T |
---|
96 | // Variable Tscale=5 |
---|
97 | SetScale/P x 0,(Tscale),"", dmat |
---|
98 | SetScale/P y 0,(Tscale),"", dmat |
---|
99 | SetScale/P z 0,(Tscale),"", dmat |
---|
100 | // |
---|
101 | // t1=ticks |
---|
102 | FFT dmat // dmat is now COMPLEX |
---|
103 | // print (ticks-t1)/60.15 |
---|
104 | // need to multiply the scaling of the FFT result by 2Pi to get proper q-units |
---|
105 | |
---|
106 | SetScale/P x 0,(2*pi*DimDelta(dmat, 0)),"", dmat |
---|
107 | // the FFT rotates zero to the center of the y and z dimensions, so use the DimOffset |
---|
108 | SetScale/P y (2*pi*DimOffset(dmat, 1)),(2*pi*DimDelta(dmat, 1)),"", dmat |
---|
109 | SetScale/P z (2*pi*DimOffset(dmat, 2)),(2*pi*DimDelta(dmat, 2)),"", dmat |
---|
110 | |
---|
111 | End |
---|
112 | |
---|
113 | |
---|
114 | Function fDoCorrection_old(dmat) |
---|
115 | Wave/C dmat |
---|
116 | |
---|
117 | // do the convolution with the cube here |
---|
118 | // - a lengthy triple for loop |
---|
119 | // Note that x-dimension is N/2+1 now, since it was a real input |
---|
120 | // y,z dims are unchanged |
---|
121 | Variable xDim=DimSize(dmat,0),yDim=DimSize(dmat,1),zDim=DimSize(dmat,2) |
---|
122 | Variable ii,jj,kk |
---|
123 | Variable xVal,yVal,zVal |
---|
124 | Variable xfac,yfac,zfac |
---|
125 | Variable dimOff0,dimOff1,dimOff2,delta0,delta1,delta2 |
---|
126 | |
---|
127 | NVAR Tscale=root:FFT_T |
---|
128 | NVAR Nedge = root:FFT_N |
---|
129 | if(WaveExists(SincWave) && SameDimensions(note(SincWave)) ) |
---|
130 | //just do the matrix multiplication |
---|
131 | Wave SincWave=SincWave |
---|
132 | MultiThread dmat *= SincWave |
---|
133 | return(0) |
---|
134 | else |
---|
135 | //create the cube correction matrix |
---|
136 | Make/O/N=(xDim,yDim,zDim) SincWave |
---|
137 | |
---|
138 | dimOff0 = DimOffset(dmat, 0) |
---|
139 | dimOff1 = DimOffset(dmat, 1) |
---|
140 | dimOff2 = DimOffset(dmat, 2) |
---|
141 | delta0 = DimDelta(dmat,0) |
---|
142 | delta1 = DimDelta(dmat,1) |
---|
143 | delta2 = DimDelta(dmat,2) |
---|
144 | |
---|
145 | for(ii=0;ii<xDim;ii+=1) |
---|
146 | xVal = dimOff0 + ii *delta0 |
---|
147 | xVal *= Tscale/2 |
---|
148 | if(ii==0) |
---|
149 | xFac = 1 |
---|
150 | else |
---|
151 | xFac = sinc(xVal) |
---|
152 | endif |
---|
153 | for(jj=0;jj<yDim;jj+=1) |
---|
154 | yVal = dimOff1 + jj *delta1 |
---|
155 | yVal *= Tscale/2 |
---|
156 | if(jj==0) |
---|
157 | yFac = 1 |
---|
158 | else |
---|
159 | yFac = sinc(yVal) |
---|
160 | endif |
---|
161 | for(kk=0;kk<zDim;kk+=1) |
---|
162 | zVal = dimOff2 + kk *delta2 |
---|
163 | zval *= Tscale/2 |
---|
164 | if(kk==0) |
---|
165 | zFac = 1 |
---|
166 | else |
---|
167 | zFac = sinc(zVal) |
---|
168 | endif |
---|
169 | SincWave[ii][jj][kk] = xfac*yfac*zfac |
---|
170 | dmat[ii][jj][kk] *= (xfac*yfac*zfac)//*(xfac*yfac*zfac) |
---|
171 | endfor |
---|
172 | endfor |
---|
173 | endfor |
---|
174 | Note/K SincWave |
---|
175 | Note SincWave, "T="+num2str(Tscale)+";N="+num2str(Nedge)+";" |
---|
176 | endif |
---|
177 | |
---|
178 | return(0) |
---|
179 | End |
---|
180 | |
---|
181 | //returns 1 if SincWave (the note) is the same as the matrix dimensions |
---|
182 | // !! takes the values from the PANEL |
---|
183 | Function SameDimensions(str) |
---|
184 | String str |
---|
185 | |
---|
186 | NVAR Tscale=root:FFT_T |
---|
187 | NVAR Nedge = root:FFT_N |
---|
188 | if(NumberByKey("T", str ,"=",";") == Tscale && NumberByKey("N", str ,"=",";") == Nedge) |
---|
189 | return(1) |
---|
190 | else |
---|
191 | return(0) |
---|
192 | endif |
---|
193 | end |
---|
194 | |
---|
195 | Function fGetMagnitude_old(dmat) |
---|
196 | Wave/C dmat |
---|
197 | //now get the magnitude, I(q) = |F(q)|^2 |
---|
198 | // do I want magnitude, or magnitude squared? = magsqr(z) |
---|
199 | |
---|
200 | MultiThread dmat = r2polar(dmat) |
---|
201 | Redimension/R dmat //just the real part is the magnitude, throw away the complex part |
---|
202 | MultiThread dmat *= dmat //square it |
---|
203 | //dmat is now a purely real matrix |
---|
204 | |
---|
205 | End |
---|
206 | |
---|
207 | //dmat is a real matrix at this point |
---|
208 | // (1) use channel sharing (not yet implemented) - then will need to normalize by q^2 rather than nBins |
---|
209 | // --- channel sharing method does not seem to be as good... |
---|
210 | // (2) don't bin points beyond Qmax (done) |
---|
211 | // |
---|
212 | Function fDoBinning(dmat,normalize) |
---|
213 | Wave dmat |
---|
214 | Variable normalize |
---|
215 | |
---|
216 | Variable xDim=DimSize(dmat,0),yDim=DimSize(dmat,1),zDim=DimSize(dmat,2) |
---|
217 | Variable ii,jj,kk |
---|
218 | Variable qX,qY,qZ,qTot |
---|
219 | Variable binIndex,val |
---|
220 | NVAR FFT_QmaxReal= root:FFT_QmaxReal |
---|
221 | |
---|
222 | Make/O/D/N=(yDim*2) iBin,qBin,nBin |
---|
223 | qBin[] = 0 + p*DimDelta(dmat, 1)/2 //use bins of 1/2 the width of the reciprocal lattice |
---|
224 | SetScale/P x,0,DimDelta(dmat,1)/2,"",qBin |
---|
225 | |
---|
226 | iBin = 0 |
---|
227 | nBin = 0 //number of intensities added to each bin |
---|
228 | |
---|
229 | //loop through everything, and add it all up |
---|
230 | Variable dimOff0,dimOff1,dimOff2,delta0,delta1,delta2 |
---|
231 | Variable pt,pt1,fra |
---|
232 | dimOff0 = DimOffset(dmat, 0) |
---|
233 | dimOff1 = DimOffset(dmat, 1) |
---|
234 | dimOff2 = DimOffset(dmat, 2) |
---|
235 | delta0 = DimDelta(dmat,0) |
---|
236 | delta1 = DimDelta(dmat,1) |
---|
237 | delta2 = DimDelta(dmat,2) |
---|
238 | |
---|
239 | for(ii=0;ii<xDim;ii+=1) |
---|
240 | qX = dimOff0 + ii *delta0 |
---|
241 | |
---|
242 | for(jj=0;jj<yDim;jj+=1) |
---|
243 | qY = dimOff1 + jj *delta1 |
---|
244 | |
---|
245 | for(kk=0;kk<zDim;kk+=1) |
---|
246 | qZ = dimOff2 + kk*delta2 |
---|
247 | qTot = sqrt(qX^2 + qY^2 + qZ^2) |
---|
248 | if(qTot < FFT_QmaxReal) //only take the time to use the good values |
---|
249 | // binning method |
---|
250 | binIndex = trunc(x2pnt(qBin, qTot)) |
---|
251 | val = dmat[ii][jj][kk] |
---|
252 | if (numType(val)==0) //count only the good points, ignore Nan or Inf |
---|
253 | iBin[binIndex] += val |
---|
254 | nBin[binIndex] += 1 |
---|
255 | endif |
---|
256 | // |
---|
257 | // channel sharing method (not as good) |
---|
258 | // pt = (qTot - DimOffset(qBin,0))/DimDelta(qBin,0) //fractional point |
---|
259 | // val = dmat[ii][jj][kk] |
---|
260 | // if (numType(val)==0) //count only the good points, ignore Nan or Inf |
---|
261 | // pt1 = trunc(pt) |
---|
262 | // fra = pt - pt1 |
---|
263 | // iBin[pt1] += (1-fra)*val |
---|
264 | // iBin[pt1+1] += fra*val |
---|
265 | // endif |
---|
266 | endif |
---|
267 | endfor |
---|
268 | endfor |
---|
269 | endfor |
---|
270 | |
---|
271 | iBin /= nBin |
---|
272 | //normalize, iBin[0] will be NaN so use point[1], or the first "real" value |
---|
273 | ii=0 |
---|
274 | do |
---|
275 | if(nBin[ii] == 0 || nbin[ii] == 1) |
---|
276 | DeletePoints 0,1, iBin,qBin,nBin //keep deleting the first point if there were zero or one bins |
---|
277 | else |
---|
278 | val = ibin[ii] |
---|
279 | if(numtype(val)==0) |
---|
280 | break |
---|
281 | endif |
---|
282 | ii+=1 |
---|
283 | endif |
---|
284 | while(ii<numpnts(ibin)) |
---|
285 | |
---|
286 | // by channel sharing....(not as good) |
---|
287 | // iBin /= qBin^2 |
---|
288 | //delete first two points (q=0 and q=Qmin) |
---|
289 | // DeletePoints 0,2, iBin,qBin,nBin |
---|
290 | // val = iBin[0] |
---|
291 | |
---|
292 | if(normalize) |
---|
293 | iBin /= val //then normalize by the first point |
---|
294 | endif |
---|
295 | |
---|
296 | Duplicate/O iBin, iBinAll |
---|
297 | Duplicate/O qBin, qBinAll |
---|
298 | Duplicate/O nBin, nBinAll |
---|
299 | //now truncate qBin at FFT_QmaxReal |
---|
300 | FindLevel/Q/P qBin, FFT_QmaxReal //level is reported as a point number, V_LevelX |
---|
301 | DeletePoints trunc(V_LevelX)+1, (numpnts(qBin) - trunc(V_LevelX)-1) , iBin,qBin,nBin |
---|
302 | |
---|
303 | return(0) |
---|
304 | End |
---|
305 | |
---|
306 | //look for NaN in w1, delete point in w1 and w2 |
---|
307 | Function DeleteNaNInf_XY(w1,w2) |
---|
308 | Wave w1,w2 |
---|
309 | |
---|
310 | Variable num=numpnts(w1),ii |
---|
311 | |
---|
312 | ii=0 |
---|
313 | do |
---|
314 | if(numtype(w1[ii]) !=0) |
---|
315 | //bad point, delete |
---|
316 | DeletePoints ii, 1, w1,w2 |
---|
317 | //don't increment ii, but update (decrement) num |
---|
318 | num = numpnts(w1) |
---|
319 | else |
---|
320 | //increment ii |
---|
321 | ii += 1 |
---|
322 | endif |
---|
323 | while(ii<num) |
---|
324 | End |
---|
325 | |
---|
326 | |
---|
327 | |
---|
328 | Function fDoCorrection(dmat) |
---|
329 | Wave/C dmat |
---|
330 | |
---|
331 | // do the convolution with the cube here |
---|
332 | // - a lengthy triple for loop |
---|
333 | // Note that x-dimension is N/2+1 now, since it was a real input |
---|
334 | // y,z dims are unchanged |
---|
335 | Variable xDim=DimSize(dmat,0),yDim=DimSize(dmat,1),zDim=DimSize(dmat,2) |
---|
336 | Variable ii,jj,kk |
---|
337 | Variable xVal,yVal,zVal |
---|
338 | Variable xfac,yfac,zfac |
---|
339 | Variable dimOff0,dimOff1,dimOff2,delta0,delta1,delta2 |
---|
340 | |
---|
341 | NVAR Tscale=root:FFT_T |
---|
342 | NVAR Nedge = root:FFT_N |
---|
343 | if(WaveExists(SincWave) && SameDimensions(note(SincWave)) ) |
---|
344 | //just do the matrix multiplication |
---|
345 | Wave SincWave=SincWave |
---|
346 | MatrixOP/C tmp = dmat*SincWave |
---|
347 | |
---|
348 | // preserve the scaling |
---|
349 | SetScale/P x 0,DimDelta(dmat, 0),"", tmp |
---|
350 | SetScale/P y DimOffset(dmat, 1),DimDelta(dmat, 1),"", tmp |
---|
351 | SetScale/P z DimOffset(dmat, 2),DimDelta(dmat, 2),"", tmp |
---|
352 | |
---|
353 | //dmat=tmp |
---|
354 | return(0) |
---|
355 | else |
---|
356 | //create the cube correction matrix |
---|
357 | Make/O/N=(xDim,yDim,zDim) SincWave |
---|
358 | |
---|
359 | dimOff0 = DimOffset(dmat, 0) |
---|
360 | dimOff1 = DimOffset(dmat, 1) |
---|
361 | dimOff2 = DimOffset(dmat, 2) |
---|
362 | delta0 = DimDelta(dmat,0) |
---|
363 | delta1 = DimDelta(dmat,1) |
---|
364 | delta2 = DimDelta(dmat,2) |
---|
365 | |
---|
366 | for(ii=0;ii<xDim;ii+=1) |
---|
367 | xVal = dimOff0 + ii *delta0 |
---|
368 | xVal *= Tscale/2 |
---|
369 | if(ii==0) |
---|
370 | xFac = 1 |
---|
371 | else |
---|
372 | xFac = sinc(xVal) |
---|
373 | endif |
---|
374 | for(jj=0;jj<yDim;jj+=1) |
---|
375 | yVal = dimOff1 + jj *delta1 |
---|
376 | yVal *= Tscale/2 |
---|
377 | if(jj==0) |
---|
378 | yFac = 1 |
---|
379 | else |
---|
380 | yFac = sinc(yVal) |
---|
381 | endif |
---|
382 | for(kk=0;kk<zDim;kk+=1) |
---|
383 | zVal = dimOff2 + kk *delta2 |
---|
384 | zval *= Tscale/2 |
---|
385 | if(kk==0) |
---|
386 | zFac = 1 |
---|
387 | else |
---|
388 | zFac = sinc(zVal) |
---|
389 | endif |
---|
390 | SincWave[ii][jj][kk] = xfac*yfac*zfac |
---|
391 | dmat[ii][jj][kk] *= (xfac*yfac*zfac)//*(xfac*yfac*zfac) |
---|
392 | endfor |
---|
393 | endfor |
---|
394 | endfor |
---|
395 | Duplicate/O/C dmat,tmp //slow the first time |
---|
396 | Note/K SincWave |
---|
397 | Note SincWave, "T="+num2str(Tscale)+";N="+num2str(Nedge)+";" |
---|
398 | endif |
---|
399 | |
---|
400 | return(0) |
---|
401 | End |
---|
402 | |
---|
403 | Function fGetMagnitude(tmp) |
---|
404 | Wave/C tmp |
---|
405 | //now get the magnitude, I(q) = |F(q)|^2 |
---|
406 | // do I want magnitude, or magnitude squared? = magsqr(z) |
---|
407 | |
---|
408 | MatrixOP tmp2 = real(r2polar(tmp)) |
---|
409 | |
---|
410 | MatrixOP/O dmat=tmp2*tmp2 |
---|
411 | |
---|
412 | // preserve the scaling - MatrixOP does NOT |
---|
413 | SetScale/P x 0,DimDelta(tmp, 0),"", dmat |
---|
414 | SetScale/P y DimOffset(tmp, 1),DimDelta(tmp, 1),"", dmat |
---|
415 | SetScale/P z DimOffset(tmp, 2),DimDelta(tmp, 2),"", dmat |
---|
416 | Killwaves/Z tmp,tmp2 |
---|
417 | // |
---|
418 | // clean up before exiting |
---|
419 | //dmat is now a purely real matrix |
---|
420 | return(0) |
---|
421 | End |
---|
422 | |
---|
423 | |
---|
424 | // w is a real (2D) matrix at this point |
---|
425 | // -- it comes from a slice of dmat, so it has proper wave scaling |
---|
426 | // (2) don't bin points beyond Qmax (done) |
---|
427 | // |
---|
428 | Function fDoBinning_Scaled2D(w,normalize) |
---|
429 | Wave w |
---|
430 | Variable normalize |
---|
431 | |
---|
432 | Variable xDim=DimSize(w,0),yDim=DimSize(w,1) |
---|
433 | Variable ii,jj |
---|
434 | Variable qX,qY,qTot |
---|
435 | Variable binIndex,val |
---|
436 | NVAR FFT_QmaxReal= root:FFT_QmaxReal |
---|
437 | |
---|
438 | Make/O/D/N=(yDim*2) iBin_2d,qBin_2d,nBin_2d |
---|
439 | qBin_2d[] = 0 + p*DimDelta(w, 1)/2 //use bins of 1/2 the width of the reciprocal lattice |
---|
440 | SetScale/P x,0,DimDelta(w,1)/2,"",qBin_2d |
---|
441 | |
---|
442 | iBin_2d = 0 |
---|
443 | nBin_2d = 0 //number of intensities added to each bin |
---|
444 | |
---|
445 | //loop through everything, and add it all up |
---|
446 | Variable dimOff0,dimOff1,delta0,delta1 |
---|
447 | Variable pt,pt1,fra |
---|
448 | dimOff0 = DimOffset(w, 0) |
---|
449 | dimOff1 = DimOffset(w, 1) |
---|
450 | delta0 = DimDelta(w,0) |
---|
451 | delta1 = DimDelta(w,1) |
---|
452 | |
---|
453 | for(ii=0;ii<xDim;ii+=1) |
---|
454 | qX = dimOff0 + ii *delta0 |
---|
455 | |
---|
456 | for(jj=0;jj<yDim;jj+=1) |
---|
457 | qY = dimOff1 + jj *delta1 |
---|
458 | |
---|
459 | // qZ = dimOff2 + kk*delta2 |
---|
460 | qTot = sqrt(qX^2 + qY^2) |
---|
461 | if(qTot < FFT_QmaxReal) //only take the time to use the good values |
---|
462 | // binning method |
---|
463 | binIndex = trunc(x2pnt(qBin_2d, qTot)) |
---|
464 | val = w[ii][jj] |
---|
465 | if (numType(val)==0) //count only the good points, ignore Nan or Inf |
---|
466 | iBin_2d[binIndex] += val |
---|
467 | nBin_2d[binIndex] += 1 |
---|
468 | endif |
---|
469 | // |
---|
470 | |
---|
471 | endif |
---|
472 | endfor |
---|
473 | endfor |
---|
474 | |
---|
475 | iBin_2d /= nBin_2d |
---|
476 | //normalize, iBin[0] will be NaN so use point[1], or the first "real" value |
---|
477 | ii=0 |
---|
478 | do |
---|
479 | if(nBin_2d[ii] == 0 || nBin_2d[ii] == 1) |
---|
480 | DeletePoints 0,1, iBin_2d,qBin_2d,nBin_2d //keep deleting the first point if there were zero or one bins |
---|
481 | else |
---|
482 | val = iBin_2d[ii] |
---|
483 | if(numtype(val)==0) |
---|
484 | break |
---|
485 | endif |
---|
486 | ii+=1 |
---|
487 | endif |
---|
488 | while(ii<numpnts(iBin_2d)) |
---|
489 | |
---|
490 | // by channel sharing....(not as good) |
---|
491 | // iBin /= qBin^2 |
---|
492 | //delete first two points (q=0 and q=Qmin) |
---|
493 | // DeletePoints 0,2, iBin,qBin,nBin |
---|
494 | // val = iBin[0] |
---|
495 | |
---|
496 | if(normalize) |
---|
497 | iBin_2d /= val //then normalize by the first point |
---|
498 | endif |
---|
499 | |
---|
500 | Duplicate/O iBin_2d, iBinAll_2d |
---|
501 | Duplicate/O qBin_2d, qBinAll_2d |
---|
502 | Duplicate/O nBin_2d, nBinAll_2d |
---|
503 | //now truncate qBin at FFT_QmaxReal |
---|
504 | FindLevel/Q/P qBin_2d, FFT_QmaxReal //level is reported as a point number, V_LevelX |
---|
505 | DeletePoints trunc(V_LevelX)+1, (numpnts(qBin_2d) - trunc(V_LevelX)-1) , iBin_2d,qBin_2d,nBin_2d |
---|
506 | |
---|
507 | return(0) |
---|
508 | End |
---|
509 | |
---|
510 | |
---|
511 | // this is how the 3D viewer in the image Processing macros works |
---|
512 | // to get the correct plane from the 3D matrix |
---|
513 | Function get2DSlice(dmat) |
---|
514 | wave dmat |
---|
515 | |
---|
516 | ImageTransform/G=4 transposeVol dmat |
---|
517 | WAVE M_VolumeTranspose |
---|
518 | ImageTransform/P=0 getPlane M_VolumeTranspose |
---|
519 | WAVE M_ImagePlane |
---|
520 | Duplicate/O M_ImagePlane detPlane |
---|
521 | Duplicate/O M_ImagePlane logP |
---|
522 | |
---|
523 | NVAR FFT_N=root:FFT_N |
---|
524 | detPlane[FFT_N/2][FFT_N/2] = NaN //hopefully this trims out the singularity at the center |
---|
525 | logP = log(detPlane) |
---|
526 | |
---|
527 | fDoBinning_Scaled2D(detPlane,0) //last param = normalize y/n |
---|
528 | |
---|
529 | KillWaves/Z M_VolumeTranspose,M_ImagePlane |
---|
530 | |
---|
531 | return(0) |
---|
532 | end |
---|
533 | |
---|
534 | |
---|
535 | // using a 2D FFT slice, and a folder of real data, interpolate the FFT result to |
---|
536 | // match the q values of the data |
---|
537 | // |
---|
538 | // qz is assumed to be zero. |
---|
539 | // |
---|
540 | Function Interpolate2DSliceToData(folderStr) |
---|
541 | String folderStr |
---|
542 | |
---|
543 | Wave calc = root:detPlane |
---|
544 | Wave data = $("root:"+folderStr+":"+folderStr+"_lin") |
---|
545 | |
---|
546 | Duplicate/O data,interp2DSlice //keeps the scaling of the data |
---|
547 | |
---|
548 | Variable rowOff,colOff,rowDel,colDel |
---|
549 | rowOff = DimOffset(data,0) |
---|
550 | colOff = DimOffset(data,1) |
---|
551 | rowDel = DimDelta(data,0) |
---|
552 | colDel = DimDelta(data,1) |
---|
553 | |
---|
554 | // see pnt2x for explanation |
---|
555 | // DimOffset(data, 0) + p *DimDelta(data,0) |
---|
556 | // DimOffset(data, 1) + q *DimDelta(data,1) |
---|
557 | |
---|
558 | interp2DSlice = Interp2D (calc, rowOff + p*rowDel, colOff + q*colDel ) |
---|
559 | |
---|
560 | Duplicate/O interp2DSlice interp2DSlice_log |
---|
561 | interp2DSlice_log = log(interp2DSlice) |
---|
562 | |
---|
563 | return(0) |
---|
564 | end |
---|