source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/VSANS/V_IQ_Utilities.ipf @ 1035

Last change on this file since 1035 was 1035, checked in by srkline, 6 years ago

changes to streamline the data plotting of 1D data, in preparation for different modes of combining detector panels. Also will allow better integration with protocols to combine 1D data, which can now be part of the protocol.

Other changes, but I can't remember whtat they were...

File size: 15.0 KB
Line 
1#pragma TextEncoding = "MacRoman"               // For details execute DisplayHelpTopic "The TextEncoding Pragma"
2#pragma rtGlobals=3             // Use modern global access method and strict wave access.
3
4
5//
6// Operation does no scaling, only the basic (default) trim of the ends, concatenate, sort, and save
7// -- if data has been converted to WORK and the solid angle correction was done, then the data
8//   is per unit solid angle, and matches up - at least the simulated data does...
9//   It should match up in real VSANS data since the flux conditions are identical for
10//   all panels, only the geometry is different.
11//
12//
13// V_DataPlotting.ipf is where the I(q) panel is drawn and the binning is set
14//
15// see the VCALC BinAllMiddlePanels() for an example of this
16// see the binning routines in VC_DetectorBinning_Utils.ipf for the details
17//
18
19// TODO
20//
21// -- verify the binning for slit mode. Looks correct, but verify
22// -- DOCUMENT
23//
24// x- detector "B" is currently skipped since the calibration waves are not faked
25//    when the raw data is loaded. Then the qxqyqz waves are not generated.
26//
27// x- REDO the logic here. It's a mess, and will get the calculation wrong
28//
29// x- figure out the binning type (where is it set for VSANS?)
30// x- don't know, so currently VSANS binning type is HARD-WIRED
31// x- figure out when this needs to be called to (force) re-calculate I vs Q
32//
33
34
35Strconstant ksBinTypeStr = "One;Two;Four;Slit Mode;"
36
37// NOTE
38// this is the master conversion function
39// ***Use no others
40// *** When other bin types are developed, DO NOT reassign these numbers.
41//  instead, skip the old numbers and assign new ones.
42// old modes can be removed from the string constant ksBinTypeStr (above), but the
43// mode numbers are what many different binning, plotting, and reduction functions are
44// switching on. In the future, it may be necessary to change the key (everywhere) to a string
45// switch, but for now, stick with the numbers.
46Function V_BinTypeStr2Num(binStr)
47        String binStr
48       
49        Variable binType
50        strswitch(binStr)       // string switch
51                case "One":
52                        binType = 1
53                        break           // exit from switch
54                case "Two":
55                        binType = 2
56                        break           // exit from switch
57                case "Four":
58                        binType = 3
59                        break           // exit from switch
60                case "Slit Mode":
61                        binType = 4
62                        break           // exit from switch
63
64                default:                        // optional default expression executed
65                        binType = 0
66                        Abort "Binning mode not found"// when no case matches
67        endswitch       
68        return(binType)
69end
70
71Function V_QBinAllPanels(folderStr,binType)
72        String folderStr
73        Variable binType
74
75        // do the back, middle, and front separately
76       
77//      figure out the binning type (where is it set?)
78        Variable ii,delQ
79        String detStr
80
81//      binType = V_GetBinningPopMode()
82
83//// TODO:
84//
85//      Back detector is handled spearately since there is nothing to combine
86//
87        delQ = SetDeltaQ(folderStr,"B")
88       
89        // dispatch based on binning type
90        if(binType == 1 || binType == 2 || binType == 3)
91                VC_fDoBinning_QxQy2D(folderStr, "B")            //normal binning, nothing to combine
92        endif
93
94// TODO -- this is only a temporary fix for slit mode   
95        if(binType == 4)
96                /// this is for a tall, narrow slit mode       
97                VC_fBinDetector_byRows(folderStr,"B")
98        endif   
99
100
101
102// these are the binning types where detectors are not combined
103// other combined binning is below the loop
104        for(ii=0;ii<ItemsInList(ksDetectorListNoB);ii+=1)
105                detStr = StringFromList(ii, ksDetectorListNoB, ";")
106               
107                // set delta Q for binning
108                delQ = SetDeltaQ(folderStr,detStr)
109               
110                // dispatch based on binning type
111                if(binType==1)
112                        VC_fDoBinning_QxQy2D(folderStr,detStr)
113                endif
114               
115                // TODO -- this is only a temporary fix for slit mode   
116                if(binType == 4)
117                        /// this is for a tall, narrow slit mode       
118                        VC_fBinDetector_byRows(folderStr,detStr)
119                endif   
120               
121        endfor
122       
123        // bin in pairs
124        if(binType == 2)
125                VC_fDoBinning_QxQy2D(folderStr,"MLR")
126                VC_fDoBinning_QxQy2D(folderStr,"MTB")
127                VC_fDoBinning_QxQy2D(folderStr,"FLR")
128                VC_fDoBinning_QxQy2D(folderStr,"FTB")   
129        endif
130       
131        // bin everything on front or middle together
132        if(binType == 3)
133                VC_fDoBinning_QxQy2D(folderStr,"MLRTB")
134                VC_fDoBinning_QxQy2D(folderStr,"FLRTB")
135        endif
136
137        return(0)
138End
139
140// concatenates and sorts the 1D data in "type" WORK folder
141// uses the current display if type==""
142//
143Function V_ConcatenateForSave(type,binType)
144        String type
145        Variable binType
146       
147// get the current display type, if null string passed in
148        SVAR curtype = root:Packages:NIST:VSANS:Globals:gCurDispType
149       
150        if(strlen(type)==0)
151                type = curType
152        endif
153
154// trim the data if needed
155        // remove the q=0 point from the back detector, if it's there
156        // does not need to know binType
157        V_RemoveQ0_B(type)
158
159// concatenate the data sets
160// TODO x- figure out which binning was used (this is done in V_1DConcatenate())
161        // clear the old tmp waves first, if they still exist
162        SetDataFolder $("root:Packages:NIST:VSANS:"+type)
163        Killwaves/Z tmp_q,tmp_i,tmp_s
164        setDataFolder root:
165        V_1DConcatenate(type,binType)
166       
167// sort the data set
168        V_TmpSort1D(type)
169       
170        return(0)
171End
172
173//
174// this is only called from the button on the data panel
175// so the type is the currently displayed type, and the binning is from the panel
176//
177Function V_SimpleSave1DData(type,saveName)
178        String type,saveName
179
180//
181// get the current display type, if null string passed in
182        SVAR curtype = root:Packages:NIST:VSANS:Globals:gCurDispType
183        Variable binType = V_GetBinningPopMode()
184       
185        V_ConcatenateForSave(curType,binType)
186       
187// write out the data set to a file
188        if(strlen(saveName)==0)
189                Execute "V_GetNameForSave()"
190                SVAR newName = root:saveName
191                saveName = newName
192        endif
193       
194        V_Write1DData(curtype,saveName)
195
196End
197
198
199Proc V_GetNameForSave(str)
200        String str
201        String/G root:saveName=str
202End
203
204
205// blindly assumes that there is only one zero at the top of the wave
206// could be more sophisticated in the future...
207Function V_RemoveQ0_B(type)
208        String type
209       
210        SetDataFolder $("root:Packages:NIST:VSANS:"+type)
211
212        WAVE/Z qBin = qBin_qxqy_B
213        WAVE/Z iBin = iBin_qxqy_B
214        WAVE/Z eBin = eBin_qxqy_B
215        WAVE/Z nBin = nBin_qxqy_B
216        WAVE/Z iBin2 = iBin2_qxqy_B
217
218        if(qBin[0] == 0)
219                DeletePoints 0, 1, qBin,iBin,eBin,nBin,iBin2
220        endif
221       
222        SetDataFolder root:
223        return(0)
224end
225
226
227// concatentate data in folderStr
228//
229// TODO:
230// x- this currently ignores the binning type (one, two, etc. )
231// -- this currently assumes that all of the waves exist
232// -- need robust error checking for wave existence
233// -- wave names are hard-wired and their name and location may be different in the future
234// x- if different averaging options were chosen (bin type of 2, 4 etc) then
235//    although waves may exist, they may not be the right ones to use. There
236//    will be a somewhat complex selection process
237// x- detector B is currently skipped
238//
239// this seems like a lot of extra work to do something so simple...but it's better than a loop
240//
241//  root:Packages:NIST:VSANS:RAW:iBin_qxqy_FB
242//
243// binType = 1 = one
244// binType = 2 = two
245// binType = 3 = four
246// binType = 4 = Slit Mode
247//
248// if binType is passed in as -9999, get the binning mode from the popup
249// otherwise the value is assumed good (from a protocol)
250//
251Function V_1DConcatenate(folderStr,binType)
252        String folderStr
253        Variable binType
254       
255        if(binType==-9999)
256                binType = V_GetBinningPopMode()
257        endif   
258       
259        SetDataFolder $("root:Packages:NIST:VSANS:"+folderStr)
260
261        //kill these waves before starting, or the new concatenation will be added to the old
262        KillWaves/Z tmp_q,tmp_i,tmp_s
263       
264        if(binType == 1)       
265                Wave/Z q_fb = qBin_qxqy_FB
266                Wave/Z q_ft = qBin_qxqy_FT
267                Wave/Z q_fl = qBin_qxqy_FL
268                Wave/Z q_fr = qBin_qxqy_FR
269                Wave/Z q_mb = qBin_qxqy_MB
270                Wave/Z q_mt = qBin_qxqy_MT
271                Wave/Z q_ml = qBin_qxqy_ML
272                Wave/Z q_mr = qBin_qxqy_MR
273                Wave/Z q_b = qBin_qxqy_B
274       
275                Concatenate/NP {q_fb,q_ft,q_fl,q_fr,q_mb,q_mt,q_ml,q_mr,q_b}, tmp_q
276               
277                Wave/Z i_fb = iBin_qxqy_FB
278                Wave/Z i_ft = iBin_qxqy_FT
279                Wave/Z i_fl = iBin_qxqy_FL
280                Wave/Z i_fr = iBin_qxqy_FR
281                Wave/Z i_mb = iBin_qxqy_MB
282                Wave/Z i_mt = iBin_qxqy_MT
283                Wave/Z i_ml = iBin_qxqy_ML
284                Wave/Z i_mr = iBin_qxqy_MR
285                Wave/Z i_b = iBin_qxqy_B
286               
287                Concatenate/NP {i_fb,i_ft,i_fl,i_fr,i_mb,i_mt,i_ml,i_mr,i_b}, tmp_i
288       
289                Wave/Z s_fb = eBin_qxqy_FB
290                Wave/Z s_ft = eBin_qxqy_FT
291                Wave/Z s_fl = eBin_qxqy_FL
292                Wave/Z s_fr = eBin_qxqy_FR
293                Wave/Z s_mb = eBin_qxqy_MB
294                Wave/Z s_mt = eBin_qxqy_MT
295                Wave/Z s_ml = eBin_qxqy_ML
296                Wave/Z s_mr = eBin_qxqy_MR
297                Wave/Z s_b = eBin_qxqy_B
298               
299                Concatenate/NP {s_fb,s_ft,s_fl,s_fr,s_mb,s_mt,s_ml,s_mr,s_b}, tmp_s
300        endif
301
302        if(binType == 2)       
303                Wave/Z q_ftb = qBin_qxqy_FTB
304                Wave/Z q_flr = qBin_qxqy_FLR
305                Wave/Z q_mtb = qBin_qxqy_MTB
306                Wave/Z q_mlr = qBin_qxqy_MLR
307                Wave/Z q_b = qBin_qxqy_B
308       
309                Concatenate/NP {q_ftb,q_flr,q_mtb,q_mlr,q_b}, tmp_q
310               
311                Wave/Z i_ftb = iBin_qxqy_FTB
312                Wave/Z i_flr = iBin_qxqy_FLR
313                Wave/Z i_mtb = iBin_qxqy_MTB
314                Wave/Z i_mlr = iBin_qxqy_MLR
315                Wave/Z i_b = iBin_qxqy_B
316               
317                Concatenate/NP {i_ftb,i_flr,i_mtb,i_mlr,i_b}, tmp_i
318       
319                Wave/Z s_ftb = eBin_qxqy_FTB
320                Wave/Z s_flr = eBin_qxqy_FLR
321                Wave/Z s_mtb = eBin_qxqy_MTB
322                Wave/Z s_mlr = eBin_qxqy_MLR
323                Wave/Z s_b = eBin_qxqy_B
324               
325                Concatenate/NP {s_ftb,s_flr,s_mtb,s_mlr,s_b}, tmp_s
326        endif
327
328        if(binType == 3)       
329                Wave/Z q_flrtb = qBin_qxqy_FLRTB
330                Wave/Z q_mlrtb = qBin_qxqy_MLRTB
331                Wave/Z q_b = qBin_qxqy_B
332       
333                Concatenate/NP {q_flrtb,q_mlrtb,q_b}, tmp_q
334               
335                Wave/Z i_flrtb = iBin_qxqy_FLRTB
336                Wave/Z i_mlrtb = iBin_qxqy_MLRTB
337                Wave/Z i_b = iBin_qxqy_B
338               
339                Concatenate/NP {i_flrtb,i_mlrtb,i_b}, tmp_i
340       
341                Wave/Z s_flrtb = eBin_qxqy_FLRTB
342                Wave/Z s_mlrtb = eBin_qxqy_MLRTB
343                Wave/Z s_b = eBin_qxqy_B
344               
345                Concatenate/NP {s_flrtb,s_mlrtb,s_b}, tmp_s
346        endif
347
348// TODO - This is the identical set of waves as for the case of binType = 1.
349// they have the same names, but are averaged differently since it's slit mode.
350// I have separated this, since in practice the TB panels are probably best to ignore
351// and NOT include in the averaging since the Qy range is so limited.
352        if(binType == 4)       
353                Wave/Z q_fb = qBin_qxqy_FB
354                Wave/Z q_ft = qBin_qxqy_FT
355                Wave/Z q_fl = qBin_qxqy_FL
356                Wave/Z q_fr = qBin_qxqy_FR
357                Wave/Z q_mb = qBin_qxqy_MB
358                Wave/Z q_mt = qBin_qxqy_MT
359                Wave/Z q_ml = qBin_qxqy_ML
360                Wave/Z q_mr = qBin_qxqy_MR
361                Wave/Z q_b = qBin_qxqy_B
362       
363                Concatenate/NP {q_fb,q_ft,q_fl,q_fr,q_mb,q_mt,q_ml,q_mr,q_b}, tmp_q
364               
365                Wave/Z i_fb = iBin_qxqy_FB
366                Wave/Z i_ft = iBin_qxqy_FT
367                Wave/Z i_fl = iBin_qxqy_FL
368                Wave/Z i_fr = iBin_qxqy_FR
369                Wave/Z i_mb = iBin_qxqy_MB
370                Wave/Z i_mt = iBin_qxqy_MT
371                Wave/Z i_ml = iBin_qxqy_ML
372                Wave/Z i_mr = iBin_qxqy_MR
373                Wave/Z i_b = iBin_qxqy_B
374               
375                Concatenate/NP {i_fb,i_ft,i_fl,i_fr,i_mb,i_mt,i_ml,i_mr,i_b}, tmp_i
376       
377                Wave/Z s_fb = eBin_qxqy_FB
378                Wave/Z s_ft = eBin_qxqy_FT
379                Wave/Z s_fl = eBin_qxqy_FL
380                Wave/Z s_fr = eBin_qxqy_FR
381                Wave/Z s_mb = eBin_qxqy_MB
382                Wave/Z s_mt = eBin_qxqy_MT
383                Wave/Z s_ml = eBin_qxqy_ML
384                Wave/Z s_mr = eBin_qxqy_MR
385                Wave/Z s_b = eBin_qxqy_B
386               
387                Concatenate/NP {s_fb,s_ft,s_fl,s_fr,s_mb,s_mt,s_ml,s_mr,s_b}, tmp_s
388        endif
389
390
391
392
393// Can't kill here, since they are still needed to sort and write out!
394//      KillWaves/Z tmp_q,tmp_i,tmp_s,tmp_res0,tmp_res1,tmp_res2,tmp_res3       
395       
396        SetDataFolder root:
397       
398        return(0)               
399End
400
401// TODO:
402// -- resolution waves are ignored, since they don't exist (yet)
403// -- only a sort is done, no rescaling of data sets
404//    (it's too late now anyways, since the data was concatenated)
405//
406// see Auto_Sort() in the SANS Automation ipf for the rest of the details of
407// how to combine the resolution waves (they also need to be concatenated, which is currently not done)
408//
409Function V_TmpSort1D(folderStr)
410        String folderStr
411       
412        SetDataFolder $("root:Packages:NIST:VSANS:"+folderStr)
413
414        Wave qw = tmp_q
415        Wave iw = tmp_i
416        Wave sw = tmp_s
417       
418//      Sort qw, qw,iw,sw,res0,res1,res2,res3
419
420        Sort qw, qw,iw,sw
421
422
423        SetDataFolder root:
424        return(0)
425End
426
427
428// TODO
429// -- currently, this function is NOT called by anything
430// needs:
431// -- trim the beamstop out (based on shadow)
432// -- trim out zero q from the file (bad actor in analysis functions)
433// -- trim num from the highQ end or lowQ end?
434// -- splits the res wave into individual waves in anticipation of concatenation
435//   -- or -- deal with the res wave after?
436//
437//
438//
439Function V_Trim1DData(folderStr,nEnd)
440        String folderStr
441        Variable nEnd
442
443        if(DataFolderExists("root:"+folderStr)  == 0)
444                return(0)
445        endif
446               
447        SetDataFolder $("root:"+folderStr)
448       
449        Wave qw = $(folderStr + "_q")
450        Wave iw = $(folderStr + "_i")
451        Wave sw = $(folderStr + "_s")
452        Wave res = $(folderStr + "_res")
453       
454        variable num,ii
455       
456        num=numpnts(qw)
457        //Break out resolution wave into separate waves
458        Make/O/D/N=(num) res0 = res[p][0]               // sigQ
459        Make/O/D/N=(num) res1 = res[p][1]               // qBar
460        Make/O/D/N=(num) res2 = res[p][2]               // fshad
461        Make/O/D/N=(num) res3 = res[p][3]               // qvals
462       
463        // trim off the last nEnd points from everything
464        DeletePoints num-nEnd,nEnd, qw,iw,sw,res0,res1,res2,res3
465       
466        // delete all points where the shadow is < 0.98
467        num=numpnts(qw)
468        for(ii=0;ii<num;ii+=1)
469                if(res2[ii] < 0.98)
470                        DeletePoints ii,1, qw,iw,sw,res0,res1,res2,res3
471                        num -= 1
472                        ii -= 1
473                endif
474        endfor
475       
476////Put resolution contents back???
477//              reswave[][0] = res0[p]
478//              reswave[][1] = res1[p]
479//              reswave[][2] = res2[p]
480//              reswave[][3] = res3[p]
481//             
482                       
483        SetDataFolder root:
484        return(0)
485end
486
487
488
489// TODO:
490// -- this is a temporary solution before a real writer is created
491// -- resolution is not handled here (and it shouldn't be) since resolution is not known yet.
492//
493// this will bypass save dialogs
494// -- AND WILL OVERWITE DATA WITH THE SAME NAME
495//
496Function V_Write1DData(folderStr,saveName)
497        String folderStr,saveName
498       
499        String formatStr="",fullpath=""
500        Variable refnum,dialog=1
501
502        SetDataFolder $("root:Packages:NIST:VSANS:"+folderStr)
503
504        Wave qw = tmp_q
505        Wave iw = tmp_i
506        Wave sw = tmp_s
507       
508        String dataSetFolderParent,basestr
509       
510        // ParseFilePath to get path without folder name
511//      dataSetFolderParent = ParseFilePath(1,folderStr,":",1,0)
512        // ParseFilePath to get basestr
513//      basestr = ParseFilePath(0,folderStr,":",1,0)
514       
515        //make sure the waves exist
516       
517        if(WaveExists(qw) == 0)
518                Abort "q is missing"
519        endif
520        if(WaveExists(iw) == 0)
521                Abort "i is missing"
522        endif
523        if(WaveExists(sw) == 0)
524                Abort "s is missing"
525        endif
526//      if(WaveExists(resw) == 0)
527//              Abort "Resolution information is missing."
528//      endif
529       
530//      Duplicate/O qw qbar,sigQ,fs
531//      if(dimsize(resW,1) > 4)
532//              //it's USANS put -dQv back in the last 3 columns
533//              NVAR/Z dQv = USANS_dQv
534//              if(NVAR_Exists(dQv) == 0)
535//                      SetDataFolder root:
536//                      Abort "It's USANS data, and I don't know what the slit height is."
537//              endif
538//              sigQ = -dQv
539//              qbar = -dQv
540//              fs = -dQv
541//      else
542//              //it's SANS
543//              sigQ = resw[p][0]
544//              qbar = resw[p][1]
545//              fs = resw[p][2]
546//      endif
547//     
548
549        PathInfo catPathName
550        fullPath = S_Path + saveName
551
552        Open refnum as fullpath
553
554        fprintf refnum,"Combined data written from folder %s on %s\r\n",folderStr,(date()+" "+time())
555
556// TODO -- make this work for 6-columns
557//      formatStr = "%15.4g %15.4g %15.4g %15.4g %15.4g %15.4g\r\n"     
558//      fprintf refnum, "The 6 columns are | Q (1/A) | I(Q) (1/cm) | std. dev. I(Q) (1/cm) | sigmaQ | meanQ | ShadowFactor|\r\n"       
559//      wfprintf refnum,formatStr,qw,iw,sw,sigQ,qbar,fs
560
561        //currently, only three columns
562        formatStr = "%15.4g %15.4g %15.4g\r\n" 
563        fprintf refnum, "The 3 columns are | Q (1/A) | I(Q) (1/cm) | std. dev. I(Q) (1/cm)\r\n"
564
565        wfprintf refnum,formatStr,qw,iw,sw
566        Close refnum
567       
568//      KillWaves/Z sigQ,qbar,fs
569       
570        SetDataFolder root:
571        return(0)
572End
Note: See TracBrowser for help on using the repository browser.