source: sans/Dev/trunk/NCNR_User_Procedures/Reduction/VSANS/V_Utilities_Comparisons.ipf @ 1242

Last change on this file since 1242 was 1242, checked in by srkline, 3 years ago

updating the IgorVersion? pragma to v7.0 for all files to be consistent.

File size: 13.4 KB
Line 
1#pragma TextEncoding = "MacRoman"
2#pragma rtGlobals=3             // Use modern global access method and strict wave access.
3#pragma IgorVersion = 7.00
4
5//
6//
7// utility procedures for comparing values in files to ensure that certain operations
8// such as transmssion, adding raw files, etc. can be properly completed
9//
10//
11// basic results are that:
12//  matching = 1 = true = OK
13//  no match = 0 = false = NOT OK
14//
15// V_CloseEnough tolerance is an absolute value
16// so passing 0.01*val_1 = 1% tolerance, as long as val_1 can't be zero
17//
18// SEP 2018 -- increased the tolerance to 2%, since I was getting false differences
19// especially for the lateral offset after switching from trans->scatter configs. Panel
20// was returning to postion, but within 2% (since the value was near zero)
21//
22
23
24// Function to test if two raw data files were collected at identical conditions.
25// this function does as many test as I can think of to compare the conditions.
26//
27// A test like this is to be used before two raw data files can be added together.
28//
29// TODO:
30// long list of points that need to match up to be sure that the conditions are all the same
31//
32//
33// depending on how long these checks take, may want a way to bypass this with a flag
34//
35// if any of the match conditions fail, exit immediately
36//
37//
38Function V_RawFilesMatchConfig(fname1,fname2)
39        String fname1,fname2
40
41        Variable ii
42        String detStr
43       
44// collimation conditions       
45// wavelength   
46        if(!V_FP_Value_Match(V_getWavelength,fname1,fname2))
47                Print "Wavelength does not match"
48                return(0)       //no match
49        endif
50       
51// wavelength spread
52        if(!V_FP_Value_Match(V_getWavelength_spread,fname1,fname2))
53                Print "Wavelength spread does not match"
54                return(0)       //no match
55        endif
56
57// monochromator type   
58        if(!V_String_Value_Match(V_getMonochromatorType,fname1,fname2))
59                Print "Monochromator type does not match"
60                return(0)
61        endif
62       
63// number of guides     (or narrow_slit, etc.)
64        if(!V_String_Value_Match(V_getNumberOfGuides,fname1,fname2))
65                Print "Number of guides does not match"
66                return(0)
67        endif
68       
69       
70//// detector conditions
71//// loop over all of the detectors
72
73// detector distance and offset
74// I DON'T need to check all of the distances, just three will do
75        if(!V_FP2_Value_Match(V_getDet_NominalDistance,fname1,fname2,"FL"))
76                Print "Front carriage distance does not match"
77                return(0)       //no match
78        endif
79
80        if(!V_FP2_Value_Match(V_getDet_NominalDistance,fname1,fname2,"ML"))
81                Print "Middle carriage distance does not match"
82                return(0)       //no match
83        endif
84       
85        if(!V_FP2_Value_Match(V_getDet_NominalDistance,fname1,fname2,"B"))
86                Print "Back carriage distance does not match"
87                return(0)       //no match
88        endif
89       
90       
91// I DO need to check all of the offset values
92        //// only return value for B and L/R detectors. everything else returns zero
93        //Function V_getDet_LateralOffset(fname,detStr)
94        //
95        //// only return values for T/B. everything else returns zero
96        //Function V_getDet_VerticalOffset(fname,detStr)
97        for(ii=0;ii<ItemsInList(ksDetectorListAll);ii+=1)
98                detStr = StringFromList(ii, ksDetectorListAll, ";")
99                if(!V_FP2_Value_Match(V_getDet_LateralOffset,fname1,fname2,detStr))
100                        Print "Lateral offset does not match for "+detStr
101                        return(0)       //no match
102                endif
103                if(!V_FP2_Value_Match(V_getDet_VerticalOffset,fname1,fname2,detStr))
104                        Print "Vertical offset does not match for "+detStr
105                        return(0)       //no match
106                endif
107        endfor
108       
109
110// messy - if the shape=circle, then look at size
111// but if shape=rectangle, look at height and width
112// source aperture shape, size
113        if(!V_String_Value_Match(V_getSourceAp_shape,fname1,fname2))
114                Print "Source aperture shape does not match"
115                return(0)
116        endif
117// sample aperture shape, size
118        if(!V_String_Value_Match(V_getSampleAp2_shape,fname1,fname2))
119                Print "Sample aperture shape does not match"
120                return(0)
121        endif
122
123        return(1)               // passed all of the tests, OK, it's a match
124End
125
126
127// given an open beam file, to identify the allowable transmission measurements,
128// the conditions to meet are:
129//
130// wavelength
131// wavelength spread
132// detector distance(s)
133// detector offset(s) (this ensures that the same panel is catching the direct beam)
134//
135// ? do I need to check beam stop locations ?
136//
137Function V_Trans_Match_Open(fname1,fname2)
138        String fname1,fname2
139
140        Variable ii
141        String detStr
142       
143// collimation conditions       
144// wavelength   
145        if(!V_FP_Value_Match(V_getWavelength,fname1,fname2))
146                return(0)       //no match
147        endif
148       
149// wavelength spread
150        if(!V_FP_Value_Match(V_getWavelength_spread,fname1,fname2))
151                return(0)       //no match
152        endif
153
154//// monochromator type
155//      if(!V_String_Value_Match(V_getMonochromatorType,fname1,fname2))
156//              return(0)
157//      endif
158//     
159//// number of guides   (or narrow_slit, etc.)
160//      if(!V_String_Value_Match(V_getNumberOfGuides,fname1,fname2))
161//              return(0)
162//      endif
163       
164       
165//// detector conditions
166//// loop over all of the detectors
167
168// detector distance and offset
169// I DON'T need to check all of the distances, just three will do
170        if(!V_FP2_Value_Match(V_getDet_NominalDistance,fname1,fname2,"FL"))
171                return(0)       //no match
172        endif
173
174        if(!V_FP2_Value_Match(V_getDet_NominalDistance,fname1,fname2,"ML"))
175                return(0)       //no match
176        endif
177       
178        if(!V_FP2_Value_Match(V_getDet_NominalDistance,fname1,fname2,"B"))
179                return(0)       //no match
180        endif
181       
182       
183//// ???Do I need to check all of the offset values
184//      //// only return value for B and L/R detectors. everything else returns zero
185//      //Function V_getDet_LateralOffset(fname,detStr)
186//      //
187//      //// only return values for T/B. everything else returns zero
188//      //Function V_getDet_VerticalOffset(fname,detStr)
189//      for(ii=0;ii<ItemsInList(ksDetectorListAll);ii+=1)
190//              detStr = StringFromList(ii, ksDetectorListAll, ";")
191//              if(!V_FP2_Value_Match(V_getDet_LateralOffset,fname1,fname2,detStr))
192//                      return(0)       //no match
193//              endif
194//              if(!V_FP2_Value_Match(V_getDet_VerticalOffset,fname1,fname2,detStr))
195//                      return(0)       //no match
196//              endif
197//      endfor
198
199// only check the panel position for the actual panel used for the open beam measurement
200        detStr = V_getReduction_BoxPanel(fname1)
201        if(!V_FP2_Value_Match(V_getDet_LateralOffset,fname1,fname2,detStr))
202                return(0)       //no match
203        endif
204
205        return(1)               // passed all of the tests, OK, it's a match
206End
207
208
209// given a transmission file, identify the possible scattering files:
210//
211// first, the group ID must match
212// then, as far as configurations:
213//
214// need to match
215// wavelength
216// wavelength spread
217// (I think that is all - since the transmission is only dependent on these values)
218//
219Function V_Scatter_Match_Trans(fname1,fname2)
220        String fname1,fname2
221
222        Variable ii
223        String detStr
224       
225// collimation conditions       
226// wavelength   
227        if(!V_FP_Value_Match(V_getWavelength,fname1,fname2))
228                return(0)       //no match
229        endif
230       
231// wavelength spread
232        if(!V_FP_Value_Match(V_getWavelength_spread,fname1,fname2))
233                return(0)       //no match
234        endif
235
236//// monochromator type
237//      if(!V_String_Value_Match(V_getMonochromatorType,fname1,fname2))
238//              return(0)
239//      endif
240//     
241//// number of guides   (or narrow_slit, etc.)
242//      if(!V_String_Value_Match(V_getNumberOfGuides,fname1,fname2))
243//              return(0)
244//      endif
245       
246       
247////// detector conditions
248////// loop over all of the detectors
249//
250//// detector distance and offset
251//// I DON'T need to check all of the distances, just three will do
252//      if(!V_FP2_Value_Match(V_getDet_NominalDistance,fname1,fname2,"FL"))
253//              return(0)       //no match
254//      endif
255//
256//      if(!V_FP2_Value_Match(V_getDet_NominalDistance,fname1,fname2,"ML"))
257//              return(0)       //no match
258//      endif
259//     
260//      if(!V_FP2_Value_Match(V_getDet_NominalDistance,fname1,fname2,"B"))
261//              return(0)       //no match
262//      endif
263//     
264//     
265//// I DO need to check all of the offset values
266//      //// only return value for B and L/R detectors. everything else returns zero
267//      //Function V_getDet_LateralOffset(fname,detStr)
268//      //
269//      //// only return values for T/B. everything else returns zero
270//      //Function V_getDet_VerticalOffset(fname,detStr)
271//      for(ii=0;ii<ItemsInList(ksDetectorListAll);ii+=1)
272//              detStr = StringFromList(ii, ksDetectorListAll, ";")
273//              if(!V_FP2_Value_Match(V_getDet_LateralOffset,fname1,fname2,detStr))
274//                      return(0)       //no match
275//              endif
276//              if(!V_FP2_Value_Match(V_getDet_VerticalOffset,fname1,fname2,detStr))
277//                      return(0)       //no match
278//              endif
279//      endfor
280
281        return(1)               // passed all of the tests, OK, it's a match
282End
283
284
285
286
287
288Function V_String_Value_Match(func,fname1,fname2)
289        FUNCREF proto_V_get_STR func
290        String fname1,fname2
291       
292        Variable match=0
293        String val1,val2
294        val1 = func(fname1)
295        val2 = func(fname2)
296       
297//      Print val1
298        match = (cmpstr(val1,val2) == 0)                // match = 1 if the strings match, 0 if they don't match
299//      print match
300       
301        return(match)
302End
303
304
305Function V_FP_Value_Match(func,fname1,fname2)
306        FUNCREF proto_V_get_FP func
307        String fname1,fname2
308       
309        Variable match=0
310        Variable val1,val2,tol
311        val1 = func(fname1)
312        val2 = func(fname2)
313       
314        if(val1 == 0 && val2 == 0)
315                return(1)               // a match
316        endif
317
318        if(val1 != 0)
319                tol = abs(0.02 * val1)
320        else
321                tol = abs(0.02 * val2)
322        endif
323       
324//      match = V_CloseEnough(val1,val2,0.01*val1)
325        match = V_CloseEnough(val1,val2,tol)
326       
327        return(match)
328End
329
330// when a detector string is needed
331Function V_FP2_Value_Match(func,fname1,fname2,detStr)
332        FUNCREF proto_V_get_FP2 func
333        String fname1,fname2,detStr
334       
335        Variable match=0
336        Variable val1,val2,tol
337        val1 = func(fname1,detStr)
338        val2 = func(fname2,detStr)
339       
340        if(val1 == 0 && val2 == 0)
341                return(1)               // a match
342        endif
343       
344        if(val1 != 0)
345                tol = abs(0.02 * val1)
346        else
347                tol = abs(0.02 * val2)
348        endif
349       
350        match = V_CloseEnough(val1,val2,tol)
351       
352        return(match)
353End
354
355
356// parse through conditions in the data file to generate a string
357// that represents the collimation condition so that the proper resolution
358// can be calculated during the averaging step
359//
360// possible values are:
361//
362// pinhole
363// pinhole_whiteBeam
364// narrowSlit
365// narrowSlit_whiteBeam
366// convergingPinholes
367//
368// graphite at this point is treated as pinhole, until I find evidence otherwise.
369//
370//
371Function/S V_IdentifyCollimation(fname)
372        String fname
373       
374        String collimationStr=""
375        String status="",guides="",typeStr=""
376        variable wb_in=0,slit=0
377       
378        guides = V_getNumberOfGuides(fname)
379        if(cmpstr(guides,"CONV_BEAMS") == 0)
380                return("convergingPinholes")
381        endif
382
383        guides = V_getNumberOfGuides(fname)
384        if(cmpstr(guides,"NARROW_SLITS") == 0)
385                slit = 1
386        endif
387       
388// TODO: still not the correct way to identify the super white beam condition
389        typeStr = V_getMonochromatorType(fname)
390        if(cmpstr(typeStr,"super_white_beam")==0)
391                if(slit == 1)
392                        return("narrowSlit_super_white_beam")
393                else
394                        return("pinhole_super_white_beam")
395                endif
396        endif
397
398
399// TODO: as of 6/2018 with the converging pinholes IN, status is "out"
400//      status = V_getConvPinholeStatus(fname)
401//      if(cmpstr(status,"IN") == 0)
402//              return("convergingPinholes")
403//      endif
404
405        status = V_getWhiteBeamStatus(fname)
406        if(cmpstr(status,"IN") == 0)
407                wb_in = 1
408        endif   
409       
410
411       
412        if(wb_in == 1 && slit == 1)
413                return("narrowSlit_whiteBeam")
414        endif
415       
416        if(wb_in == 1 && slit == 0)
417                return("pinhole_whiteBeam")
418        endif
419       
420        if(wb_in == 0 && slit == 1)
421                return("narrowSlit")
422        endif
423       
424        if(wb_in == 0 && slit == 0)
425                return("pinhole")
426        endif
427       
428        // this is an error condition = null string     
429        return(collimationStr)
430End
431
432
433// TODO -- this may not correctly mimic the enumerated type of the file
434//  but I need to fudge this somehow
435//
436// returns null string if the type cannot be deduced, calling procedure is responsible
437//  for properly handling this error condition
438//
439Function/S V_IdentifyMonochromatorType(fname)
440        String fname
441       
442        String typeStr=""
443
444// TODO: if super_white_beam, this needs to be patched in the header
445//     
446        typeStr = V_getMonochromatorType(fname)
447        if(cmpstr(typeStr,"super_white_beam")==0)
448                return(typeStr)
449        endif
450       
451       
452        if(cmpstr(V_getVelSelStatus(fname),"IN") == 0)
453                typeStr = "velocity_selector"
454        endif
455       
456        if(cmpstr(V_getWhiteBeamStatus(fname),"IN") == 0)
457                typeStr = "white_beam"
458        endif
459       
460        if(cmpstr(V_getCrystalStatus(fname),"IN") == 0)
461                typeStr = "crystal"
462        endif   
463
464
465       
466        return(typeStr)
467End
468
469
470// returns the beamstop diameter [mm]
471//
472// checks the field num_beamstops. if this is 0, then there is no beam stop in place
473//      if there is no beamtop in front of the specified detector, return 0.01mm
474//
475// if the number is non-zero, then for the middle carriage, return the BS size, which
476//  will always be the diameter, since there are only circular beamstops present.
477//
478// TODO
479//  -- for the back carriage, the numbered beam stops are:
480// (1) = 6 mm x 300 mm (RECTANGLE)
481// (2) = 12 mm diameter (CIRCLE)
482// (3) = 12 mm x 300 mm (RECTANGLE)
483//
484//              -- currently this returns the diameter of the beam stop for # 2
485//    and the width ONLY if #1 or #3 (both are 300 mm high)
486//
487Function V_IdentifyBeamstopDiameter(folderStr,detStr)
488        String folderStr,detStr
489       
490        Variable BS, dummyVal,num
491        dummyVal = 0.01         //[mm]
492       
493        if(cmpstr("F",detStr[0]) == 0)
494                // front carriage has no beamstops
495                return(dummyVal)
496        endif
497       
498        if(cmpstr("M",detStr[0]) == 0)
499                // middle carriage (2)
500                num = V_getBeamStopC2num_beamstops(folderStr)
501                if(num)
502                        BS = V_getBeamStopC2_size(folderStr)
503                else
504                        //num = 0, no beamstops in the middle.
505                        return(dummyVal)
506                endif
507        endif
508
509        if(cmpstr("B",detStr[0]) == 0)
510                // back (3)
511                num = V_getBeamStopC3num_beamstops(folderStr)
512                if(num==0)
513                        return(dummyVal)
514                endif
515               
516                if(num==2)
517                        //2 = circular beamstop
518                        BS = V_getBeamStopC3_size(folderStr)
519                else
520                        //1 or 3, these are rectangular -- return the width, since the height of both is 300 mm
521                        return(V_getBeamStopC3_width(folderStr))
522                endif
523        endif   
524       
525        return(BS)
526end
527
528
529
530//
531// tests if two values are close enough to each other
532// very useful since ICE came to be
533//
534// tol is an absolute value (since input v1 or v2 may be zero, can't reliably
535// use a percentage
536Function V_CloseEnough(v1,v2,tol)
537        Variable v1, v2, tol
538
539        if(abs(v1-v2) < tol)
540                return(1)
541        else
542                return(0)
543        endif
544End
545
Note: See TracBrowser for help on using the repository browser.