source: sasview/sansrealspace/test/sim_validation.py @ 14e4804

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since 14e4804 was a98171d, checked in by Gervaise Alina <gervyh@…>, 13 years ago

move test out of realpace folder

  • Property mode set to 100644
File size: 12.4 KB
RevLine 
[ba1d1e9]1"""
2    Validation tests for real-space simulation of I(q)
3   
4    @copyright: University of Tennessee, 2007
5    @license: This software is provided as part of the DANSE project
6"""
7import math, time, pylab
8
9try:
10    import VolumeCanvas
11    print "Testing local version"
12except:
13    print "Testing installed version"
14    import sans.realspace.VolumeCanvas as VolumeCanvas
15     
16class Validator:
17 
18    def __init__(self):
19        self.density = 0.1
[a2c1196]20        self.canvas  = None
21        self.ana     = None
[ba1d1e9]22        self.create()
23       
24    def create(self):
25        pass
26         
[a2c1196]27    def run_sim2D(self, qx, qy, density=None):
28        """
29            Calculate the mean and error of the simulation
30            @param q: q-value to calculate at
31            @param density: point density of simulation
32            #return: mean, error
33        """
34        if not density == None:
35            self.density = density
36            self.create()
37       
38        return self.canvas.getIq2DError(qx, qy)
39   
[ba1d1e9]40    def run_sim(self, q, density=None):
41        """
42            Calculate the mean and error of the simulation
43            @param q: q-value to calculate at
44            @param density: point density of simulation
45            #return: mean, error
46        """
47        if not density == None:
48            self.density = density
49            self.create()
50       
51        return self.canvas.getIqError(q)
52         
[a2c1196]53    def run_ana2D(self, qx, qy):
54        """
55            Return analytical value
56            @param q: q-value to evaluate at [float]
57            @return: analytical output [float]
58        """
59        return self.ana.runXY([qx, qy]) 
60         
[ba1d1e9]61    def run_ana(self, q):
62        """
63            Return analytical value
64            @param q: q-value to evaluate at [float]
65            @return: analytical output [float]
66        """
67        return self.ana.run(q)     
68   
69class SphereValidator(Validator):
70   
71    def __init__(self, radius=15, density = 0.01):
72        from sans.models.SphereModel import SphereModel
73       
74        self.name = 'sphere'
75        self.radius = radius
76        self.density = density
77       
78        self.ana = SphereModel()
79        self.ana.setParam('scale', 1.0)
80        self.ana.setParam('contrast', 1.0)
81        self.ana.setParam('background', 0.0)
82        self.ana.setParam('radius', radius)
83        self.create()
84       
85    def create(self):
86        canvas = VolumeCanvas.VolumeCanvas()
87        canvas.setParam('lores_density', self.density)
88        handle = canvas.add('sphere')
89        canvas.setParam('%s.radius' % handle, self.radius)
90        canvas.setParam('scale' , 1.0)
91        canvas.setParam('%s.contrast' % handle, 1.0)
92        canvas.setParam('background' , 0.0)
93        self.canvas = canvas   
94           
95class CylinderValidator(Validator):
96   
97    def __init__(self, radius=15, length=100, density = 0.01):
98        from sans.models.CylinderModel import CylinderModel
99       
100        self.name = 'cylinder'
101        self.radius = radius
102        self.length = length
103        self.density = density
104       
105        self.ana = CylinderModel()
106        self.ana.setParam('scale', 1.0)
107        self.ana.setParam('contrast', 1.0)
108        self.ana.setParam('background', 0.0)
109        self.ana.setParam('radius', radius)
110        self.ana.setParam('length', length)
[f980d4a]111        self.ana.setParam('cyl_theta', math.pi/2.0)
112        self.ana.setParam('cyl_phi', math.pi/2.0)
[ba1d1e9]113        self.create()
114       
115    def create(self):
116        canvas = VolumeCanvas.VolumeCanvas()
117        canvas.setParam('lores_density', self.density)
118        handle = canvas.add('cylinder')
119        canvas.setParam('%s.radius' % handle, self.radius)
120        canvas.setParam('%s.length' % handle, self.length)
121        canvas.setParam('scale' , 1.0)
122        canvas.setParam('%s.contrast' % handle, 1.0)
123        canvas.setParam('background' , 0.0)
124        self.canvas = canvas   
125           
126class EllipsoidValidator(Validator):
127   
128    def __init__(self, radius_a=60, radius_b=10, density = 0.01):
129        from sans.models.EllipsoidModel import EllipsoidModel
130        #from sans.models.SphereModel import SphereModel
131       
132        self.name = 'ellipsoid'
133        self.radius_a = radius_a
134        self.radius_b = radius_b
135        self.density = density
136       
137        self.ana = EllipsoidModel()
138        #self.ana = SphereModel()
139        self.ana.setParam('scale', 1.0)
140        self.ana.setParam('contrast', 1.0)
141        self.ana.setParam('background', 0.0)
142        self.ana.setParam('radius_a', radius_a)
143        self.ana.setParam('radius_b', radius_b)
144        #self.ana.setParam('radius', radius_a)
[f980d4a]145       
146        # Default orientation is there=1.57, phi=0
147        # Radius_a is along the x direction
[ba1d1e9]148
149        self.create()
150       
151    def create(self):
152        canvas = VolumeCanvas.VolumeCanvas()
153        canvas.setParam('lores_density', self.density)
154        handle = canvas.add('ellipsoid')
155        canvas.setParam('%s.radius_x' % handle, self.radius_a)
156        canvas.setParam('%s.radius_y' % handle, self.radius_b)
157        canvas.setParam('%s.radius_z' % handle, self.radius_b)
158        canvas.setParam('scale' , 1.0)
159        canvas.setParam('%s.contrast' % handle, 1.0)
160        canvas.setParam('background' , 0.0)
161        self.canvas = canvas
162           
163class HelixValidator(Validator):
164   
165    def __init__(self, density = 0.01):
166        self.name = 'helix'
167        self.density = density
168        self.create()
169       
170    def create(self):
171        canvas = VolumeCanvas.VolumeCanvas()
172        canvas.setParam('lores_density', self.density)
173        handle = canvas.add('singlehelix')
174        canvas.setParam('scale' , 1.0)
175        canvas.setParam('%s.contrast' % handle, 1.0)
176        canvas.setParam('background' , 0.0)
177        self.canvas = canvas
178        # just to write the parameters to the output file
179        self.ana = canvas
180       
181    def run_ana(self, q):
182        return 1
183
184           
185class CoreShellValidator(Validator):
186   
187    def __init__(self, radius=15, thickness=5, density = 0.01):
188        from sans.models.CoreShellModel import CoreShellModel
189       
190        self.name = 'coreshell'
191        self.radius = radius
192       
193        core_vol = 4.0/3.0*math.pi*radius*radius*radius
194        self.outer_radius = radius+thickness
195        shell_vol = 4.0/3.0*math.pi*self.outer_radius*self.outer_radius*self.outer_radius - core_vol
196        self.shell_sld = -1.0*core_vol/shell_vol
197
198        self.density = density
199           
200        # Core-shell
201        sphere = CoreShellModel()
202        # Core radius
203        sphere.setParam('radius', self.radius)
204        # Shell thickness
205        sphere.setParam('thickness', thickness)
206        sphere.setParam('core_sld', 1.0)
207        sphere.setParam('shell_sld', self.shell_sld)
208        sphere.setParam('solvent_sld', 0.0)
209        sphere.setParam('background', 0.0)
210        sphere.setParam('scale', 1.0)
211        self.ana = sphere
212        self.create()
213       
214    def create(self):
215        canvas = VolumeCanvas.VolumeCanvas()       
216        canvas.setParam('lores_density', self.density)
217       
218        handle = canvas.add('sphere')
219        canvas.setParam('%s.radius' % handle, self.outer_radius)
220        canvas.setParam('%s.contrast' % handle, self.shell_sld)
221       
222        handle2 = canvas.add('sphere')
223        canvas.setParam('%s.radius' % handle2, self.radius)
224        canvas.setParam('%s.contrast' % handle2, 1.0)
225               
226        canvas.setParam('scale' , 1.0)
227        canvas.setParam('background' , 0.0)
228        self.canvas = canvas
229           
230def validate_model(validator, q_min, q_max, n_q):
231    """
232         Validate a model
233         An output file containing a comparison between
234         simulation and the analytical solution will be
235         produced.
236         
237         @param validator: validator object
238         @param q_min: minimum q
239         @param q_max: maximum q
240         @param n_q: number of q points
241         @param N: number of times to evaluate each simulation point
242    """
243   
244    q_list = pylab.arange(q_min, q_max*1.0001, (q_max-q_min)/(n_q-1))
245   
246    output = open('%s_d=%g_Iq.txt' % (validator.name, validator.density), 'w')
247    output.write("PARS: %s\n" % validator.ana.params)
248    output.write("<q>  <ana>  <sim>  <err>\n")
249    for q in q_list:
250        ana = validator.run_ana(q)
251        sim, err = validator.run_sim(q)
252        print "q=%-g  ana=%-g  sim=%-g  err=%-g  diff=%-g (%-g) %s" % (q, ana, sim, err, 
253                        (sim-ana), sim/ana, str(math.fabs(sim-ana)>err))
254        output.write("%g  %g  %g  %g\n" % (q, ana, sim, err))
255    output.close()
256       
[a2c1196]257def validate_model_2D(validator, q_min, q_max, phi, n_q):
258    """
259         Validate a model
260         An output file containing a comparison between
261         simulation and the analytical solution will be
262         produced.
263         
264         @param validator: validator object
265         @param q_min: minimum q
266         @param q_max: maximum q
267         @param n_q: number of q points
268         @param N: number of times to evaluate each simulation point
269    """
270   
271    q_list = pylab.arange(q_min, q_max*1.0001, (q_max-q_min)/(n_q-1))
272   
273    output = open('%s_d=%g_Iq2D.txt' % (validator.name, validator.density), 'w')
274    output.write("PARS: %s\n" % validator.ana.params)
275    output.write("<q>  <ana>  <sim>  <err>\n")
276    t_0 = time.time()
277    for q in q_list:
278        ana = validator.run_ana2D(q*math.cos(phi), q*math.sin(phi))
279        sim, err = validator.run_sim2D(q*math.cos(phi), q*math.sin(phi))
280        print "q=%-g  ana=%-g  sim=%-g  err=%-g  diff=%-g (%-g) %s" % (q, ana, sim, err, 
281                        (sim-ana), sim/ana, str(math.fabs(sim-ana)>err))
282        output.write("%g  %g  %g  %g\n" % (q, ana, sim, err))
283    print "Time elapsed: ", time.time()-t_0
284    output.close()
285       
[ba1d1e9]286def check_density(validator, q, d_min, d_max, n_d): 
287    """
288       Check simulation output as a function of the density
289       An output file containing a comparison between
290       simulation and the analytical solution will be
291       produced.
292       
293       @param validator: validator object
294       @param q: q-value to evaluate at
295       @param d_min: minimum density
296       @param d_max: maximum density
297       @param n_d: number of density points
298       @param N: number of times to evaluate each simulation point
299    """
300    d_list = pylab.arange(d_min, d_max*1.0001, (d_max-d_min)/(n_d-1.0))
301   
302    output = open('%s_%g_density.txt' % (validator.name, q), 'w')
303    output.write("PARS: %s\n" % validator.ana.params)
304    output.write("<density>  <ana_d>  <sim_d>  <err_d>\n")
305    ana = validator.run_ana(q)
306    for d in d_list:
307        sim, err = validator.run_sim(q, density=d)
308        print "d=%-g  ana=%-g  sim=%-g  err=%-g  diff=%-g (%g) %s" % \
309            (d, ana, sim, err, (sim-ana), (sim-ana)/ana, 
310             str(math.fabs(sim-ana)>err))
311        output.write("%g  %g  %g  %g \n" % (d, ana, sim, err))
312    output.close()
313
314   
315if __name__ == '__main__':
[a2c1196]316   
317    # 2D: Density=5, 71.2 secs for 50 points
[f980d4a]318    #vali = CoreShellValidator(radius = 15, thickness=5, density = 5.0)
[a2c1196]319    #validate_model(vali, q_min=0.001, q_max=1, n_q=50)
[f980d4a]320    #validate_model_2D(vali, q_min=0.001, q_max=1, phi=1.0, n_q=50)
[ba1d1e9]321
[a2c1196]322    # 2D: Density=2, 11.1 secs for 25 points
[ba1d1e9]323    #vali = SphereValidator(radius = 20, density = 0.02)
[a2c1196]324    #validate_model(vali, q_min=0.001, q_max=0.5, n_q=25)
325    #vali = SphereValidator(radius = 20, density = 2.0)
326    #validate_model_2D(vali, q_min=0.001, q_max=0.5, phi=1.0, n_q=25)
[ba1d1e9]327   
[a2c1196]328    # 2D: Density=1, 19.4 secs for 25 points
329    # 2D: Density=0.5, 9.8 secs for 25 points
330    #vali = CylinderValidator(radius = 20, length=100, density = 0.1)
331    #validate_model(vali, q_min=0.001, q_max=0.5, n_q=25)
[f980d4a]332    vali = CylinderValidator(radius = 20, length=100, density = 0.5)
333    validate_model_2D(vali, q_min=0.001, q_max=0.2, phi=1.0, n_q=25)
[ba1d1e9]334   
[a2c1196]335    # 2D: Density=0.5, 2.26 secs for 25 points
[ba1d1e9]336    #vali = EllipsoidValidator(radius_a = 20, radius_b=15, density = 0.05)
337    #validate_model(vali, q_min=0.001, q_max=0.5, n_q=25)
[a2c1196]338    #vali = EllipsoidValidator(radius_a = 20, radius_b=15, density = 0.5)
339    #validate_model_2D(vali, q_min=0.001, q_max=0.5, phi=1.0, n_q=25)
[ba1d1e9]340   
341    #vali = HelixValidator(density = 0.05)
342    #validate_model(vali, q_min=0.001, q_max=0.5, n_q=25)
343   
344   
Note: See TracBrowser for help on using the repository browser.