1 | #pragma TextEncoding = "MacRoman" |
---|
2 | #pragma rtGlobals=3 // Use modern global access method and strict wave access. |
---|
3 | |
---|
4 | |
---|
5 | // |
---|
6 | // this is the general writer for output of 1D averaged I(q) datasets |
---|
7 | // |
---|
8 | Function V_Write1DData(pathStr,folderStr,saveName) |
---|
9 | String pathStr,folderStr,saveName |
---|
10 | |
---|
11 | String formatStr="",fullpath="" |
---|
12 | Variable refnum,dialog=1 |
---|
13 | |
---|
14 | SetDataFolder $(pathStr+folderStr) |
---|
15 | |
---|
16 | Wave qw = tmp_q |
---|
17 | Wave iw = tmp_i |
---|
18 | Wave sw = tmp_s |
---|
19 | Wave sigQ = tmp_sq |
---|
20 | Wave qbar = tmp_qb |
---|
21 | Wave fs = tmp_fs |
---|
22 | |
---|
23 | String dataSetFolderParent,basestr |
---|
24 | |
---|
25 | // ParseFilePath to get path without folder name |
---|
26 | // dataSetFolderParent = ParseFilePath(1,folderStr,":",1,0) |
---|
27 | // ParseFilePath to get basestr |
---|
28 | // basestr = ParseFilePath(0,folderStr,":",1,0) |
---|
29 | |
---|
30 | SVAR gProtoStr = root:Packages:NIST:VSANS:Globals:Protocols:gProtoStr |
---|
31 | Wave/T proto=$("root:Packages:NIST:VSANS:Globals:Protocols:"+gProtoStr) |
---|
32 | |
---|
33 | SVAR samFiles = root:Packages:NIST:VSANS:Globals:Protocols:gSAM |
---|
34 | |
---|
35 | //make sure the waves exist |
---|
36 | |
---|
37 | if(WaveExists(qw) == 0) |
---|
38 | Abort "q is missing" |
---|
39 | endif |
---|
40 | if(WaveExists(iw) == 0) |
---|
41 | Abort "i is missing" |
---|
42 | endif |
---|
43 | if(WaveExists(sw) == 0) |
---|
44 | Abort "s is missing" |
---|
45 | endif |
---|
46 | if(WaveExists(sigQ) == 0) |
---|
47 | Abort "Resolution information is missing." |
---|
48 | endif |
---|
49 | if(WaveExists(proto) == 0) |
---|
50 | Abort "protocol information is missing." |
---|
51 | endif |
---|
52 | |
---|
53 | // Duplicate/O qw qbar,sigQ,fs |
---|
54 | // if(dimsize(resW,1) > 4) |
---|
55 | // //it's USANS put -dQv back in the last 3 columns |
---|
56 | // NVAR/Z dQv = USANS_dQv |
---|
57 | // if(NVAR_Exists(dQv) == 0) |
---|
58 | // SetDataFolder root: |
---|
59 | // Abort "It's USANS data, and I don't know what the slit height is." |
---|
60 | // endif |
---|
61 | // sigQ = -dQv |
---|
62 | // qbar = -dQv |
---|
63 | // fs = -dQv |
---|
64 | // else |
---|
65 | // //it's SANS |
---|
66 | // sigQ = resw[p][0] |
---|
67 | // qbar = resw[p][1] |
---|
68 | // fs = resw[p][2] |
---|
69 | // endif |
---|
70 | // |
---|
71 | |
---|
72 | // TODO -- not sure if I need to implement this. Update to VSANS specs if I do. |
---|
73 | // //strings can be too long to print-- must trim to 255 chars |
---|
74 | // Variable ii,num=8 |
---|
75 | // Make/O/T/N=(num) tempShortProto |
---|
76 | // for(ii=0;ii<num;ii+=1) |
---|
77 | // tempShortProto[ii] = (proto[ii])[0,240] |
---|
78 | // endfor |
---|
79 | |
---|
80 | // if the "default" trimming is used, the proto[] values will be null |
---|
81 | // fill them in with the default values |
---|
82 | String protoStr7,protoStr8 |
---|
83 | if(strlen(proto[7]) == 0) |
---|
84 | protoStr7 = "(Default) "+ ksBinTrimBegDefault |
---|
85 | else |
---|
86 | protoStr7 = proto[7] |
---|
87 | endif |
---|
88 | if(strlen(proto[8]) == 0) |
---|
89 | protoStr8 = "(Default) "+ ksBinTrimEndDefault |
---|
90 | else |
---|
91 | protoStr8 = proto[8] |
---|
92 | endif |
---|
93 | |
---|
94 | PathInfo catPathName |
---|
95 | fullPath = S_Path + saveName |
---|
96 | |
---|
97 | Open refnum as fullpath |
---|
98 | |
---|
99 | fprintf refnum,"Combined data written from folder %s on %s\r\n",folderStr,(date()+" "+time()) |
---|
100 | |
---|
101 | //insert protocol information here |
---|
102 | //-1 list of sample files |
---|
103 | //0 - bkg |
---|
104 | //1 - emp |
---|
105 | //2 - div |
---|
106 | //3 - mask |
---|
107 | //4 - abs params c2-c5 |
---|
108 | //5 - average params |
---|
109 | //6 - DRK (unused in VSANS) |
---|
110 | //7 - beginning trim points |
---|
111 | //8 - end trim points |
---|
112 | fprintf refnum, "SAM: %s\r\n",samFiles |
---|
113 | fprintf refnum, "BGD: %s\r\n",proto[0] |
---|
114 | fprintf refnum, "EMP: %s\r\n",Proto[1] |
---|
115 | fprintf refnum, "DIV: %s\r\n",Proto[2] |
---|
116 | fprintf refnum, "MASK: %s\r\n",Proto[3] |
---|
117 | fprintf refnum, "ABS Parameters (3-6): %s\r\n",Proto[4] |
---|
118 | fprintf refnum, "Average Choices: %s\r\n",Proto[5] |
---|
119 | fprintf refnum, "Beginning Trim Points: %s\r\n",ProtoStr7 |
---|
120 | fprintf refnum, "End Trim Points: %s\r\n",ProtoStr8 |
---|
121 | fprintf refnum, "COLLIMATION=%s\r\n",proto[9] |
---|
122 | |
---|
123 | // TODO |
---|
124 | // x- make this work for 6-columns (or??) |
---|
125 | formatStr = "%15.4g %15.4g %15.4g %15.4g %15.4g %15.4g\r\n" |
---|
126 | fprintf refnum, "The 6 columns are | Q (1/A) | I(Q) (1/cm) | std. dev. I(Q) (1/cm) | sigmaQ | meanQ | ShadowFactor|\r\n" |
---|
127 | wfprintf refnum,formatStr,qw,iw,sw,sigQ,qbar,fs |
---|
128 | |
---|
129 | // three column vresion |
---|
130 | // formatStr = "%15.4g %15.4g %15.4g\r\n" |
---|
131 | // fprintf refnum, "The 3 columns are | Q (1/A) | I(Q) (1/cm) | std. dev. I(Q) (1/cm)\r\n" |
---|
132 | // |
---|
133 | // wfprintf refnum,formatStr,qw,iw,sw |
---|
134 | |
---|
135 | |
---|
136 | Close refnum |
---|
137 | |
---|
138 | // KillWaves/Z sigQ,qbar,fs |
---|
139 | Print "Data written to: ",fullpath |
---|
140 | |
---|
141 | SetDataFolder root: |
---|
142 | return(0) |
---|
143 | End |
---|
144 | |
---|
145 | |
---|
146 | // |
---|
147 | // this is the general writer for output of 1D averaged I(q) datasets |
---|
148 | // this version is limited to three column data where there is no |
---|
149 | // resolution information present |
---|
150 | // |
---|
151 | Function V_Write1DData_3Col(pathStr,folderStr,saveName) |
---|
152 | String pathStr,folderStr,saveName |
---|
153 | |
---|
154 | String formatStr="",fullpath="" |
---|
155 | Variable refnum,dialog=1 |
---|
156 | |
---|
157 | SetDataFolder $(pathStr+folderStr) |
---|
158 | |
---|
159 | Wave qw = tmp_q |
---|
160 | Wave iw = tmp_i |
---|
161 | Wave sw = tmp_s |
---|
162 | // Wave sigQ = tmp_sq |
---|
163 | // Wave qbar = tmp_qb |
---|
164 | // Wave fs = tmp_fs |
---|
165 | |
---|
166 | String dataSetFolderParent,basestr |
---|
167 | |
---|
168 | // ParseFilePath to get path without folder name |
---|
169 | // dataSetFolderParent = ParseFilePath(1,folderStr,":",1,0) |
---|
170 | // ParseFilePath to get basestr |
---|
171 | // basestr = ParseFilePath(0,folderStr,":",1,0) |
---|
172 | |
---|
173 | SVAR gProtoStr = root:Packages:NIST:VSANS:Globals:Protocols:gProtoStr |
---|
174 | Wave/T proto=$("root:Packages:NIST:VSANS:Globals:Protocols:"+gProtoStr) |
---|
175 | |
---|
176 | SVAR samFiles = root:Packages:NIST:VSANS:Globals:Protocols:gSAM |
---|
177 | |
---|
178 | //make sure the waves exist |
---|
179 | |
---|
180 | if(WaveExists(qw) == 0) |
---|
181 | Abort "q is missing" |
---|
182 | endif |
---|
183 | if(WaveExists(iw) == 0) |
---|
184 | Abort "i is missing" |
---|
185 | endif |
---|
186 | if(WaveExists(sw) == 0) |
---|
187 | Abort "s is missing" |
---|
188 | endif |
---|
189 | // if(WaveExists(sigQ) == 0) |
---|
190 | // Abort "Resolution information is missing." |
---|
191 | // endif |
---|
192 | if(WaveExists(proto) == 0) |
---|
193 | Abort "protocol information is missing." |
---|
194 | endif |
---|
195 | |
---|
196 | |
---|
197 | // if the "default" trimming is used, the proto[] values will be null |
---|
198 | // fill them in with the default values |
---|
199 | String protoStr7,protoStr8 |
---|
200 | if(strlen(proto[7]) == 0) |
---|
201 | protoStr7 = "(Default) "+ ksBinTrimBegDefault |
---|
202 | else |
---|
203 | protoStr7 = proto[7] |
---|
204 | endif |
---|
205 | if(strlen(proto[8]) == 0) |
---|
206 | protoStr8 = "(Default) "+ ksBinTrimEndDefault |
---|
207 | else |
---|
208 | protoStr8 = proto[8] |
---|
209 | endif |
---|
210 | |
---|
211 | PathInfo catPathName |
---|
212 | fullPath = S_Path + saveName |
---|
213 | |
---|
214 | Open refnum as fullpath |
---|
215 | |
---|
216 | fprintf refnum,"Combined data written from folder %s on %s\r\n",folderStr,(date()+" "+time()) |
---|
217 | |
---|
218 | //insert protocol information here |
---|
219 | //-1 list of sample files |
---|
220 | //0 - bkg |
---|
221 | //1 - emp |
---|
222 | //2 - div |
---|
223 | //3 - mask |
---|
224 | //4 - abs params c2-c5 |
---|
225 | //5 - average params |
---|
226 | //6 - DRK (unused in VSANS) |
---|
227 | //7 - beginning trim points |
---|
228 | //8 - end trim points |
---|
229 | fprintf refnum, "SAM: %s\r\n",samFiles |
---|
230 | fprintf refnum, "BGD: %s\r\n",proto[0] |
---|
231 | fprintf refnum, "EMP: %s\r\n",Proto[1] |
---|
232 | fprintf refnum, "DIV: %s\r\n",Proto[2] |
---|
233 | fprintf refnum, "MASK: %s\r\n",Proto[3] |
---|
234 | fprintf refnum, "ABS Parameters (3-6): %s\r\n",Proto[4] |
---|
235 | fprintf refnum, "Average Choices: %s\r\n",Proto[5] |
---|
236 | fprintf refnum, "Beginning Trim Points: %s\r\n",ProtoStr7 |
---|
237 | fprintf refnum, "End Trim Points: %s\r\n",ProtoStr8 |
---|
238 | fprintf refnum, "COLLIMATION=%s\r\n",proto[9] |
---|
239 | |
---|
240 | |
---|
241 | // three column version |
---|
242 | formatStr = "%15.4g %15.4g %15.4g\r\n" |
---|
243 | fprintf refnum, "The 3 columns are | Q (1/A) | I(Q) (1/cm) | std. dev. I(Q) (1/cm)\r\n" |
---|
244 | // |
---|
245 | wfprintf refnum,formatStr,qw,iw,sw |
---|
246 | |
---|
247 | Close refnum |
---|
248 | |
---|
249 | // KillWaves/Z sigQ,qbar,fs |
---|
250 | Print "Data written to: ",fullpath |
---|
251 | |
---|
252 | SetDataFolder root: |
---|
253 | return(0) |
---|
254 | End |
---|
255 | |
---|
256 | |
---|
257 | // |
---|
258 | // This saves the data in individual files for each detector panel. They are meant only for |
---|
259 | // troubleshooting, but the files are in the general ascii format (without resolution) |
---|
260 | // so only three columns are written out |
---|
261 | // |
---|
262 | // this will bypass save dialogs |
---|
263 | // -- AND WILL OVERWRITE DATA WITH THE SAME NAME |
---|
264 | // |
---|
265 | Function V_Write1DData_Individual(pathStr,folderStr,saveName,exten,binType) |
---|
266 | String pathStr,folderStr,saveName,exten |
---|
267 | Variable binType |
---|
268 | |
---|
269 | String formatStr="",fullpath="",item,fileName,detList |
---|
270 | Variable refnum,num,ii |
---|
271 | |
---|
272 | SetDataFolder $(pathStr+folderStr) |
---|
273 | |
---|
274 | NVAR gIgnoreB = root:Packages:NIST:VSANS:Globals:gIgnoreDetB |
---|
275 | |
---|
276 | // while in the proper data folder, loop through the detector files |
---|
277 | // and write out each individual panel (or sets of panels) as specified |
---|
278 | // by the binning type. |
---|
279 | // |
---|
280 | // copy the desired files over to tmp_q, tmp_i, and tmp_s, then |
---|
281 | // pass to a worker Function |
---|
282 | // |
---|
283 | |
---|
284 | // |
---|
285 | // ksBinType1 = "FT;FB;FL;FR;MT;MB;ML;MR;B;" //these are the "active" extensions |
---|
286 | // ksBinType2 = "FTB;FLR;MTB;MLR;B;" |
---|
287 | // ksBinType3 = "FLRTB;MLRTB;B;" |
---|
288 | // ksBinType4 = "FL;FR;ML;MR;B;" //in SLIT mode, disregard the T/B panels |
---|
289 | |
---|
290 | |
---|
291 | switch(binType) |
---|
292 | case 1: // 9 sets |
---|
293 | detList = ksBinType1 |
---|
294 | break |
---|
295 | case 2: // 5 sets |
---|
296 | detList = ksBinType2 |
---|
297 | break |
---|
298 | case 3: // 3 sets |
---|
299 | detList = ksBinType3 |
---|
300 | break |
---|
301 | case 4: // 5 sets |
---|
302 | detList = ksBinType4 |
---|
303 | break |
---|
304 | case 5: // 4 sets |
---|
305 | detList = ksBinType5 |
---|
306 | break |
---|
307 | case 6: // 3 sets |
---|
308 | detList = ksBinType6 |
---|
309 | break |
---|
310 | case 7: // 4 sets |
---|
311 | detList = ksBinType7 |
---|
312 | break |
---|
313 | |
---|
314 | default: |
---|
315 | // do nothing, just close |
---|
316 | |
---|
317 | endswitch |
---|
318 | |
---|
319 | num=ItemsInList(detList) |
---|
320 | for(ii=0;ii<num;ii+=1) |
---|
321 | SetDataFolder $(pathStr+folderStr) |
---|
322 | |
---|
323 | item=StringFromList(ii, detList) |
---|
324 | |
---|
325 | if(gIgnoreB && cmpstr(item,"B") == 0) |
---|
326 | //do nothing |
---|
327 | else |
---|
328 | fileName = saveName + "_"+item+"."+exten |
---|
329 | Wave qWave = $("qBin_qxqy_"+item) |
---|
330 | Wave iWave = $("iBin_qxqy_"+item) |
---|
331 | Wave eWave = $("eBin_qxqy_"+item) |
---|
332 | KillWaves/Z tmp_q, tmp_i, tmp_s |
---|
333 | Duplicate/O qWave tmp_q |
---|
334 | Duplicate/O iWave tmp_i |
---|
335 | Duplicate/O eWave tmp_s |
---|
336 | V_Write1DData_3Col(pathStr,folderStr,fileName) |
---|
337 | endif |
---|
338 | |
---|
339 | endfor |
---|
340 | |
---|
341 | SetDataFolder root: |
---|
342 | return(0) |
---|
343 | End |
---|
344 | |
---|
345 | |
---|
346 | |
---|
347 | |
---|
348 | |
---|
349 | // TODO: |
---|
350 | // -- this is a temporary solution before a real writer is created |
---|
351 | // -- resolution is not generated here (and it shouldn't be) since resolution is not known yet. |
---|
352 | // -- but a real writer will need to be aware of resolution, and there may be different forms |
---|
353 | // |
---|
354 | // This saves the data in Igor Text format, an ASCII format, but NOT standard SANS columns |
---|
355 | // No concatenation is done. This is meant to be used for input to TRIM, or for general troubleshooting |
---|
356 | // |
---|
357 | // |
---|
358 | // this will bypass save dialogs |
---|
359 | // -- AND WILL OVERWRITE DATA WITH THE SAME NAME |
---|
360 | // |
---|
361 | Function V_Write1DData_ITX(pathStr,folderStr,saveName,binType) |
---|
362 | String pathStr,folderStr,saveName |
---|
363 | Variable binType |
---|
364 | |
---|
365 | String formatStr="",fullpath="" |
---|
366 | Variable refnum,dialog=1 |
---|
367 | |
---|
368 | SetDataFolder $(pathStr+folderStr) |
---|
369 | |
---|
370 | |
---|
371 | //TODO |
---|
372 | //-- make sure the waves exist |
---|
373 | |
---|
374 | // if(WaveExists(qw) == 0) |
---|
375 | // Abort "q is missing" |
---|
376 | // endif |
---|
377 | // if(WaveExists(iw) == 0) |
---|
378 | // Abort "i is missing" |
---|
379 | // endif |
---|
380 | // if(WaveExists(sw) == 0) |
---|
381 | // Abort "s is missing" |
---|
382 | // endif |
---|
383 | // if(WaveExists(resw) == 0) |
---|
384 | // Abort "Resolution information is missing." |
---|
385 | // endif |
---|
386 | |
---|
387 | // Duplicate/O qw qbar,sigQ,fs |
---|
388 | // if(dimsize(resW,1) > 4) |
---|
389 | // //it's USANS put -dQv back in the last 3 columns |
---|
390 | // NVAR/Z dQv = USANS_dQv |
---|
391 | // if(NVAR_Exists(dQv) == 0) |
---|
392 | // SetDataFolder root: |
---|
393 | // Abort "It's USANS data, and I don't know what the slit height is." |
---|
394 | // endif |
---|
395 | // sigQ = -dQv |
---|
396 | // qbar = -dQv |
---|
397 | // fs = -dQv |
---|
398 | // else |
---|
399 | // //it's SANS |
---|
400 | // sigQ = resw[p][0] |
---|
401 | // qbar = resw[p][1] |
---|
402 | // fs = resw[p][2] |
---|
403 | // endif |
---|
404 | // |
---|
405 | |
---|
406 | |
---|
407 | |
---|
408 | // TODO: |
---|
409 | // -- currently I'm using the Save comand and the /B flag |
---|
410 | // to save the data as Igor Text format, since otherwise the command string would be |
---|
411 | // too long. Need to come up with an Igor-demo friendly save here |
---|
412 | // |
---|
413 | // -- see V_ExportProtocol() for a quick example of how to generate the .ITX format |
---|
414 | // |
---|
415 | // -- need a reader/plotter capable of handling this data. The regular data loader won't handle |
---|
416 | // all the different number of columns present, or the ITX format. See V_DataPlotting and duplicate these routines |
---|
417 | // Most of these routines take "winNameStr" as an argument, so I may be able to use them |
---|
418 | // |
---|
419 | // -- do I want to add the /O flag to force an overwrite if there is a name conflict? |
---|
420 | |
---|
421 | PathInfo catPathName |
---|
422 | fullPath = S_Path + saveName + ".itx" |
---|
423 | |
---|
424 | // Open refnum as fullpath |
---|
425 | // fprintf refnum,"Individual data sets written from folder %s on %s\r\n",folderStr,(date()+" "+time()) |
---|
426 | |
---|
427 | String waveStr="" |
---|
428 | // can be a multiple number of columns |
---|
429 | |
---|
430 | switch(binType) |
---|
431 | case 1: // 9 sets = 27 waves! |
---|
432 | waveStr = "qBin_qxqy_B;iBin_qxqy_B;eBin_qxqy_B;" |
---|
433 | waveStr += "qBin_qxqy_ML;iBin_qxqy_ML;eBin_qxqy_ML;" |
---|
434 | waveStr += "qBin_qxqy_MR;iBin_qxqy_MR;eBin_qxqy_MR;" |
---|
435 | waveStr += "qBin_qxqy_MT;iBin_qxqy_MT;eBin_qxqy_MT;" |
---|
436 | waveStr += "qBin_qxqy_MB;iBin_qxqy_MB;eBin_qxqy_MB;" |
---|
437 | waveStr += "qBin_qxqy_FL;iBin_qxqy_FL;eBin_qxqy_FL;" |
---|
438 | waveStr += "qBin_qxqy_FR;iBin_qxqy_FR;eBin_qxqy_FR;" |
---|
439 | waveStr += "qBin_qxqy_FT;iBin_qxqy_FT;eBin_qxqy_FT;" |
---|
440 | waveStr += "qBin_qxqy_FB;iBin_qxqy_FB;eBin_qxqy_FB;" |
---|
441 | |
---|
442 | |
---|
443 | Save/T/M="\r\n"/B waveStr as fullPath |
---|
444 | |
---|
445 | |
---|
446 | // formatStr = "%15.4g %15.4g %15.4g\r\n" |
---|
447 | // |
---|
448 | // fprintf refnum, "The 3 columns are | Q (1/A) | I(Q) (1/cm) | std. dev. I(Q) (1/cm)\r\n" |
---|
449 | // |
---|
450 | // wfprintf refnum,formatStr,qw,iw,sw |
---|
451 | break |
---|
452 | case 2: // 5 sets |
---|
453 | |
---|
454 | waveStr = "qBin_qxqy_B;iBin_qxqy_B;eBin_qxqy_B;" |
---|
455 | waveStr += "qBin_qxqy_MLR;iBin_qxqy_MLR;eBin_qxqy_MLR;qBin_qxqy_MTB;iBin_qxqy_MTB;eBin_qxqy_MTB;" |
---|
456 | waveStr += "qBin_qxqy_FLR;iBin_qxqy_FLR;eBin_qxqy_FLR;qBin_qxqy_FTB;iBin_qxqy_FTB;eBin_qxqy_FTB;" |
---|
457 | |
---|
458 | Save/T/M="\r\n"/B waveStr as fullPath |
---|
459 | |
---|
460 | // formatStr = "%15.4g %15.4g %15.4g\r\n" |
---|
461 | // |
---|
462 | // fprintf refnum, "The 3 columns are | Q (1/A) | I(Q) (1/cm) | std. dev. I(Q) (1/cm)\r\n" |
---|
463 | // |
---|
464 | // wfprintf refnum,formatStr,qw,iw,sw |
---|
465 | break |
---|
466 | case 3: // 3 sets |
---|
467 | // WAVE q1 = qBin_qxqy_B |
---|
468 | // WAVE i1 = iBin_qxqy_B |
---|
469 | // WAVE s1 = eBin_qxqy_B |
---|
470 | // WAVE q2 = qBin_qxqy_MLRTB |
---|
471 | // WAVE i2 = iBin_qxqy_MLRTB |
---|
472 | // WAVE s2 = eBin_qxqy_MLRTB |
---|
473 | // WAVE q3 = qBin_qxqy_FLRTB |
---|
474 | // WAVE i3 = iBin_qxqy_FLRTB |
---|
475 | // WAVE s3 = eBin_qxqy_FLRTB |
---|
476 | // |
---|
477 | // |
---|
478 | // Save/T/M="\r\n" q1,i1,s1,q2,i2,s2,q3,i3,s3 as fullPath |
---|
479 | |
---|
480 | waveStr = "qBin_qxqy_B;iBin_qxqy_B;eBin_qxqy_B;" |
---|
481 | waveStr += "qBin_qxqy_MLRTB;iBin_qxqy_MLRTB;eBin_qxqy_MLRTB;qBin_qxqy_FLRTB;iBin_qxqy_FLRTB;eBin_qxqy_FLRTB;" |
---|
482 | |
---|
483 | Save/T/M="\r\n"/B waveStr as fullPath |
---|
484 | |
---|
485 | |
---|
486 | // formatStr = "%15.4g %15.4g %15.4g\r\n" |
---|
487 | // |
---|
488 | // fprintf refnum, "The 3 columns are | Q (1/A) | I(Q) (1/cm) | std. dev. I(Q) (1/cm)\r\n" |
---|
489 | // |
---|
490 | // wfprintf refnum,formatStr,qw,iw,sw |
---|
491 | break |
---|
492 | case 4: // 9 sets |
---|
493 | waveStr = "qBin_qxqy_B;iBin_qxqy_B;eBin_qxqy_B;" |
---|
494 | waveStr += "qBin_qxqy_ML;iBin_qxqy_ML;eBin_qxqy_ML;" |
---|
495 | waveStr += "qBin_qxqy_MR;iBin_qxqy_MR;eBin_qxqy_MR;" |
---|
496 | waveStr += "qBin_qxqy_MT;iBin_qxqy_MT;eBin_qxqy_MT;" |
---|
497 | waveStr += "qBin_qxqy_MB;iBin_qxqy_MB;eBin_qxqy_MB;" |
---|
498 | waveStr += "qBin_qxqy_FL;iBin_qxqy_FL;eBin_qxqy_FL;" |
---|
499 | waveStr += "qBin_qxqy_FR;iBin_qxqy_FR;eBin_qxqy_FR;" |
---|
500 | waveStr += "qBin_qxqy_FT;iBin_qxqy_FT;eBin_qxqy_FT;" |
---|
501 | waveStr += "qBin_qxqy_FB;iBin_qxqy_FB;eBin_qxqy_FB;" |
---|
502 | |
---|
503 | |
---|
504 | Save/T/M="\r\n"/B waveStr as fullPath |
---|
505 | |
---|
506 | // formatStr = "%15.4g %15.4g %15.4g\r\n" |
---|
507 | // |
---|
508 | // fprintf refnum, "The 3 columns are | Q (1/A) | I(Q) (1/cm) | std. dev. I(Q) (1/cm)\r\n" |
---|
509 | // |
---|
510 | // wfprintf refnum,formatStr,qw,iw,sw |
---|
511 | break |
---|
512 | |
---|
513 | default: |
---|
514 | // do nothing, just close |
---|
515 | |
---|
516 | endswitch |
---|
517 | |
---|
518 | // Close refnum |
---|
519 | |
---|
520 | // TODO |
---|
521 | // -- clean up any waves on exit? Only if I generate extra waves |
---|
522 | // KillWaves/Z sigQ,qbar,fs |
---|
523 | |
---|
524 | SetDataFolder root: |
---|
525 | return(0) |
---|
526 | End |
---|
527 | |
---|
528 | // awkward, but can't call STRUCT from Proc |
---|
529 | Proc Vm_Write1DData_ITX() |
---|
530 | Vf_FakeSaveIQITXClick() |
---|
531 | End |
---|
532 | |
---|
533 | Function Vf_FakeSaveIQITXClick() |
---|
534 | STRUCT WMButtonAction ba |
---|
535 | ba.eventCode=2 |
---|
536 | V_SaveIQ_ButtonProc(ba) |
---|
537 | end |
---|
538 | |
---|
539 | |
---|
540 | ///////// QxQy Export ////////// |
---|
541 | // |
---|
542 | // (see the similar-named SANS routine for additonal steps - like resolution, etc.) |
---|
543 | //ASCII export of data as 8-columns qx-qy-Intensity-err-qz-sigmaQ_parall-sigmaQ_perp-fShad |
---|
544 | // + limited header information |
---|
545 | // |
---|
546 | // Jan 2019 -- first version, simply exports the basic matrix of data with no resolution information |
---|
547 | // |
---|
548 | // |
---|
549 | Function V_QxQy_Export(type,fullpath,newFileName,dialog) |
---|
550 | String type,fullpath,newFileName |
---|
551 | Variable dialog //=1 will present dialog for name |
---|
552 | |
---|
553 | String typeStr="" |
---|
554 | Variable refnum |
---|
555 | String detStr="",detSavePath |
---|
556 | |
---|
557 | SVAR gProtoStr = root:Packages:NIST:VSANS:Globals:Protocols:gProtoStr |
---|
558 | |
---|
559 | // declare, or make a fake protocol if needed (if the export type is RAW) |
---|
560 | String rawTag="" |
---|
561 | if(cmpstr(type,"RAW")==0) |
---|
562 | Make/O/T/N=(kNumProtocolSteps) proto |
---|
563 | RawTag = "RAW Data File: " |
---|
564 | else |
---|
565 | Wave/T proto=$("root:Packages:NIST:VSANS:Globals:Protocols:"+gProtoStr) |
---|
566 | endif |
---|
567 | |
---|
568 | SVAR samFiles = $("root:Packages:NIST:VSANS:"+type+":gFileList") |
---|
569 | |
---|
570 | //check each wave - MUST exist, or will cause a crash |
---|
571 | // If(!(WaveExists(data))) |
---|
572 | // Abort "data DNExist QxQy_Export()" |
---|
573 | // Endif |
---|
574 | |
---|
575 | if(dialog) |
---|
576 | PathInfo/S catPathName |
---|
577 | fullPath = DoSaveFileDialog("Save data as") |
---|
578 | If(cmpstr(fullPath,"")==0) |
---|
579 | //user cancel, don't write out a file |
---|
580 | Close/A |
---|
581 | Abort "no data file was written" |
---|
582 | Endif |
---|
583 | //Print "dialog fullpath = ",fullpath |
---|
584 | Endif |
---|
585 | |
---|
586 | // data values to populate the file header |
---|
587 | String fileName,fileDate,fileLabel |
---|
588 | Variable monCt,lambda,offset,dist,trans,thick |
---|
589 | Variable bCentX,bCentY,a2,a1a2_dist,deltaLam,bstop |
---|
590 | String a1Str |
---|
591 | Variable pixX,pixY |
---|
592 | Variable numTextLines,ii,jj,kk |
---|
593 | Variable pixSizeX,pixSizeY |
---|
594 | Variable duration |
---|
595 | |
---|
596 | numTextLines = 30 |
---|
597 | Make/O/T/N=(numTextLines) labelWave |
---|
598 | |
---|
599 | // |
---|
600 | |
---|
601 | //loop over all of the detector panels |
---|
602 | NVAR gIgnoreDetB = root:Packages:NIST:VSANS:Globals:gIgnoreDetB |
---|
603 | |
---|
604 | String detList |
---|
605 | if(gIgnoreDetB) |
---|
606 | detList = ksDetectorListNoB |
---|
607 | else |
---|
608 | detList = ksDetectorListAll |
---|
609 | endif |
---|
610 | |
---|
611 | for(kk=0;kk<ItemsInList(detList);kk+=1) |
---|
612 | |
---|
613 | detStr = StringFromList(kk, detList, ";") |
---|
614 | detSavePath = fullPath + "_" + detStr + ".DAT" |
---|
615 | |
---|
616 | pixX = V_getDet_pixel_num_x(type,detStr) |
---|
617 | pixY = V_getDet_pixel_num_y(type,detStr) |
---|
618 | |
---|
619 | fileName = newFileName |
---|
620 | fileDate = V_getDataStartTime(type) // already a string |
---|
621 | fileLabel = V_getSampleDescription(type) |
---|
622 | |
---|
623 | monCt = V_getBeamMonNormData(type) |
---|
624 | lambda = V_getWavelength(type) |
---|
625 | |
---|
626 | // TODO - switch based on panel type |
---|
627 | // V_getDet_LateralOffset(fname,detStr) |
---|
628 | // V_getDet_VerticalOffset(fname,detStr) |
---|
629 | offset = V_getDet_LateralOffset(type,detStr) |
---|
630 | |
---|
631 | dist = V_getDet_ActualDistance(type,detStr) |
---|
632 | trans = V_getSampleTransmission(type) |
---|
633 | thick = V_getSampleThickness(type) |
---|
634 | |
---|
635 | bCentX = V_getDet_beam_center_x(type,detStr) |
---|
636 | bCentY = V_getDet_beam_center_y(type,detStr) |
---|
637 | a1Str = V_getSourceAp_size(type) //already a string |
---|
638 | a2 = V_getSampleAp2_size(type) |
---|
639 | a1a2_dist = V_getSourceAp_distance(type) |
---|
640 | deltaLam = V_getWavelength_spread(type) |
---|
641 | // TODO -- decipher which beamstop, if any is actually in place |
---|
642 | // or -- V_getBeamStopC3_size(type) |
---|
643 | bstop = V_getBeamStopC2_size(type) |
---|
644 | |
---|
645 | pixSizeX = V_getDet_x_pixel_size(type,detStr) |
---|
646 | pixSizeY = V_getDet_y_pixel_size(type,detStr) |
---|
647 | |
---|
648 | duration = V_getCount_time(type) |
---|
649 | |
---|
650 | ///////// |
---|
651 | labelWave[0] = "FILE: "+fileName+" CREATED: "+fileDate |
---|
652 | labelWave[1] = "LABEL: "+fileLabel |
---|
653 | labelWave[2] = "MON CNT LAMBDA (A) DET_OFF(cm) DET_DIST(cm) TRANS THICK(cm)" |
---|
654 | labelWave[3] = num2str(monCt)+" "+num2str(lambda)+" "+num2str(offset)+" "+num2str(dist) |
---|
655 | labelWave[3] += " "+num2str(trans)+" "+num2str(thick) |
---|
656 | labelWave[4] = "BCENT(X,Y)(cm) A1(mm) A2(mm) A1A2DIST(m) DL/L BSTOP(mm)" |
---|
657 | labelWave[5] = num2str(bCentX)+" "+num2str(bCentY)+" "+a1Str+" "+num2str(a2)+" " |
---|
658 | labelWave[5] += num2str(a1a2_dist)+" "+num2str(deltaLam)+" "+num2str(bstop) |
---|
659 | labelWave[6] = "SAM: "+rawTag+samFiles |
---|
660 | labelWave[7] = "BGD: "+proto[0] |
---|
661 | labelWave[8] = "EMP: "+proto[1] |
---|
662 | labelWave[9] = "DIV: "+proto[2] |
---|
663 | labelWave[10] = "MASK: "+proto[3] |
---|
664 | labelWave[11] = "ABS Parameters (3-6): "+proto[4] |
---|
665 | labelWave[12] = "Average Choices: "+proto[5] |
---|
666 | labelWave[13] = "Collimation type: "+proto[9] |
---|
667 | labelWave[14] = "Panel="+detStr |
---|
668 | labelWave[15] = "NumXPixels="+num2str(pixX) |
---|
669 | labelWave[16] = "XPixelSize_mm="+num2str(pixSizeX) |
---|
670 | labelWave[17] = "NumYPixels="+num2str(pixY) |
---|
671 | labelWave[18] = "YPixelSize_mm="+num2str(pixSizeY) |
---|
672 | labelWave[19] = "Duration (s)="+num2str(duration) |
---|
673 | labelWave[20] = "reserved for future file definition changes" |
---|
674 | labelWave[21] = "reserved for future file definition changes" |
---|
675 | labelWave[22] = "reserved for future file definition changes" |
---|
676 | labelWave[23] = "reserved for future file definition changes" |
---|
677 | labelWave[24] = "reserved for future file definition changes" |
---|
678 | labelWave[25] = "reserved for future file definition changes" |
---|
679 | |
---|
680 | labelWave[26] = "*** Data written from "+type+" folder and may not be a fully corrected data file ***" |
---|
681 | // labelWave[20] = "Data columns are Qx - Qy - Qz - I(Qx,Qy) - Err I(Qx,Qy)" |
---|
682 | // labelWave[20] = "Data columns are Qx - Qy - I(Qx,Qy) - Qz - SigmaQ_parall - SigmaQ_perp - fSubS(beam stop shadow)" |
---|
683 | labelWave[27] = "Data columns are Qx - Qy - I(Qx,Qy) - err(I) - Qz - SigmaQ_parall - SigmaQ_perp - fSubS(beam stop shadow) - Mask" |
---|
684 | labelWave[28] = "The error wave may not be properly propagated (1/2019)" |
---|
685 | labelWave[29] = "ASCII data created " +date()+" "+time() |
---|
686 | //strings can be too long to print-- must trim to 255 chars |
---|
687 | for(jj=0;jj<numTextLines;jj+=1) |
---|
688 | labelWave[jj] = (labelWave[jj])[0,240] |
---|
689 | endfor |
---|
690 | |
---|
691 | |
---|
692 | // get the data waves for output |
---|
693 | // QxQyQz have already been calculated for VSANS data |
---|
694 | |
---|
695 | WAVE data = V_getDetectorDataW(type,detStr) |
---|
696 | WAVE data_err = V_getDetectorDataErrW(type,detStr) |
---|
697 | |
---|
698 | // JUN 2019 get the mask data |
---|
699 | WAVE MaskData = V_getDetectorDataW("MSK",detStr) |
---|
700 | |
---|
701 | |
---|
702 | // TOOD - replace hard wired paths with Read functions |
---|
703 | // hard-wired |
---|
704 | Wave qx_val = $("root:Packages:NIST:VSANS:"+type+":entry:instrument:detector_"+detStr+":qx_"+detStr) |
---|
705 | Wave qy_val = $("root:Packages:NIST:VSANS:"+type+":entry:instrument:detector_"+detStr+":qy_"+detStr) |
---|
706 | Wave qz_val = $("root:Packages:NIST:VSANS:"+type+":entry:instrument:detector_"+detStr+":qz_"+detStr) |
---|
707 | Wave qTot = $("root:Packages:NIST:VSANS:"+type+":entry:instrument:detector_"+detStr+":qTot_"+detStr) |
---|
708 | |
---|
709 | ///// calculation of the resolution function (2D) |
---|
710 | |
---|
711 | // |
---|
712 | Variable acc,ssd,lambda0,yg_d,qstar,g,L1,L2,vz_1,sdd |
---|
713 | // L1 = source to sample distance [cm] |
---|
714 | L1 = V_getSourceAp_distance(type) |
---|
715 | |
---|
716 | // L2 = sample to detector distance [cm] |
---|
717 | L2 = V_getDet_ActualDistance(type,detStr) //cm |
---|
718 | |
---|
719 | // |
---|
720 | G = 981. //! ACCELERATION OF GRAVITY, CM/SEC^2 |
---|
721 | vz_1 = 3.956E5 // 3.956E5 //! CONVERT WAVELENGTH TO VELOCITY CM/SEC |
---|
722 | acc = vz_1 |
---|
723 | SDD = L2 //1317 |
---|
724 | SSD = L1 //1627 //cm |
---|
725 | lambda0 = lambda // 15 |
---|
726 | YG_d = -0.5*G*SDD*(SSD+SDD)*(LAMBDA0/acc)^2 |
---|
727 | Print "DISTANCE BEAM FALLS DUE TO GRAVITY (CM) = ",YG_d |
---|
728 | //// Print "Gravity q* = ",-2*pi/lambda0*2*yg_d/sdd |
---|
729 | qstar = -2*pi/lambda0*2*yg_d/sdd |
---|
730 | // |
---|
731 | // |
---|
732 | //// the gravity center is not the resolution center |
---|
733 | //// gravity center = beam center |
---|
734 | //// resolution center = offset y = dy + (2)*yg_d |
---|
735 | /////************ |
---|
736 | //// do everything to write out the resolution too |
---|
737 | // // un-comment these if you want to write out qz_val and qval too, then use the proper save command |
---|
738 | // qval = CalcQval(p+1,q+1,rw[16],rw[17],rw[18],rw[26],rw[13]/10) |
---|
739 | Duplicate/O qTot,phi,r_dist |
---|
740 | Variable xctr,yctr |
---|
741 | |
---|
742 | |
---|
743 | xctr = V_getDet_beam_center_x_pix(type,detStr) |
---|
744 | yctr = V_getDet_beam_center_y_pix(type,detStr) |
---|
745 | phi = V_FindPhi( pixSizeX*((p+1)-xctr) , pixSizeY*((q+1)-yctr)+(2)*yg_d) //(dx,dy+yg_d) |
---|
746 | r_dist = sqrt( (pixSizeX*((p+1)-xctr))^2 + (pixSizeY*((q+1)-yctr)+(2)*yg_d)^2 ) //radial distance from ctr to pt |
---|
747 | |
---|
748 | //make everything in 1D now |
---|
749 | Duplicate/O qTot SigmaQX,SigmaQY,fsubS,qval |
---|
750 | Redimension/N=(pixX*pixY) SigmaQX,SigmaQY,fsubS,qval,phi,r_dist |
---|
751 | |
---|
752 | Variable ret1,ret2,ret3,nq |
---|
753 | String collimationStr |
---|
754 | |
---|
755 | |
---|
756 | collimationStr = proto[9] |
---|
757 | |
---|
758 | nq = pixX*pixY |
---|
759 | ii=0 |
---|
760 | |
---|
761 | // TODO |
---|
762 | // this loop is the slow step. it takes Å 0.7 s for F or M panels, and Å 120 s for the Back panel (6144 pts vs. 1.12e6 pts) |
---|
763 | // find some way to speed this up! |
---|
764 | // MultiThreading will be difficult as it requires all the dependent functions (HDF5 reads, etc.) to be threadsafe as well |
---|
765 | // and there are a lot of them... and I don't know if opening a file multiple times is a threadsafe operation? |
---|
766 | // -- multiple open attempts seems like a bad idea. |
---|
767 | //type = work folder |
---|
768 | |
---|
769 | // (this doesn't work...and isn't any faster) |
---|
770 | // Duplicate/O qval dum |
---|
771 | // dum = V_get2DResolution(qval,phi,r_dist,type,detStr,collimationStr,SigmaQX,SigmaQY,fsubS) |
---|
772 | |
---|
773 | v_tic() |
---|
774 | do |
---|
775 | V_get2DResolution(qval[ii],phi[ii],r_dist[ii],type,detStr,collimationStr,ret1,ret2,ret3) |
---|
776 | SigmaQX[ii] = ret1 |
---|
777 | SigmaQY[ii] = ret2 |
---|
778 | fsubs[ii] = ret3 |
---|
779 | ii+=1 |
---|
780 | while(ii<nq) |
---|
781 | v_toc() |
---|
782 | ////********************* |
---|
783 | Duplicate/O qx_val,qx_val_s |
---|
784 | Duplicate/O qy_val,qy_val_s |
---|
785 | Duplicate/O qz_val,qz_val_s |
---|
786 | Duplicate/O data,z_val_s |
---|
787 | Duplicate/O SigmaQx,sigmaQx_s |
---|
788 | Duplicate/O SigmaQy,sigmaQy_s |
---|
789 | Duplicate/O fSubS,fSubS_s |
---|
790 | Duplicate/O data_err,sw_s |
---|
791 | Duplicate/O MaskData,MaskData_s |
---|
792 | |
---|
793 | //so that double precision data is not written out |
---|
794 | Redimension/S qx_val_s,qy_val_s,qz_val_s,z_val_s,sw_s |
---|
795 | Redimension/S SigmaQx_s,SigmaQy_s,fSubS_s,MaskData_s |
---|
796 | |
---|
797 | Redimension/N=(pixX*pixY) qx_val_s,qy_val_s,qz_val_s,z_val_s,sw_s,MaskData_s |
---|
798 | |
---|
799 | //not demo-compatible, but approx 8x faster!! |
---|
800 | #if(strsearch(stringbykey("IGORKIND",IgorInfo(0),":",";"), "demo", 0 ) == -1) |
---|
801 | |
---|
802 | // Save/O/G/M="\r\n" labelWave,qx_val_s,qy_val_s,qz_val_s,z_val_s,sw_s as detSavePath // without resolution |
---|
803 | Save/O/G/M="\r\n" labelWave,qx_val_s,qy_val_s,z_val_s,sw_s,qz_val_s,SigmaQx_s,SigmaQy_s,fSubS_s,MaskData_s as detSavePath // write out the resolution information |
---|
804 | #else |
---|
805 | Open refNum as detSavePath |
---|
806 | wfprintf refNum,"%s\r\n",labelWave |
---|
807 | fprintf refnum,"\r\n" |
---|
808 | // wfprintf refNum,"%8g\t%8g\t%8g\t%8g\t%8g\r\n",qx_val_s,qy_val_s,qz_val_s,z_val_s,sw_s |
---|
809 | wfprintf refNum,"%8g\t%8g\t%8g\t%8g\t%8g\t%8g\t%8g\t%8g\t%8g\r\n",qx_val_s,qy_val_s,z_val_s,sw_s,qz_val_s,SigmaQx_s,SigmaQy_s,fSubS_s,MaskData_s |
---|
810 | Close refNum |
---|
811 | #endif |
---|
812 | |
---|
813 | KillWaves/Z qx_val_s,qy_val_s,z_val_s,qz_val_s,SigmaQx_s,SigmaQy_s,fSubS_s,sw,sw_s,MaskData_s |
---|
814 | |
---|
815 | Killwaves/Z qval,sigmaQx,SigmaQy,fSubS,phi,r_dist,MaskData |
---|
816 | |
---|
817 | Print "QxQy_Export File written: ", V_GetFileNameFromPathNoSemi(detSavePath) |
---|
818 | |
---|
819 | endfor |
---|
820 | |
---|
821 | KillWaves/Z labelWave,dum |
---|
822 | return(0) |
---|
823 | End |
---|
824 | |
---|
825 | |
---|