source: sasview/prview/perspectives/pr/pr.py @ aa749ac

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 aa749ac was 2a92852, checked in by Mathieu Doucet <doucetm@…>, 16 years ago

Updated GUI for slit smearing

  • Property mode set to 100644
File size: 28.5 KB
Line 
1#TODO: Use simview to generate P(r) and I(q) pairs in sansview.
2# Make sure the option of saving each curve is available
3# Use the I(q) curve as input and compare the output to P(r)
4
5import os
6import sys
7import wx
8import logging
9from sans.guitools.plottables import Data1D, Theory1D
10from sans.guicomm.events import NewPlotEvent, StatusEvent   
11import math, numpy
12from sans.pr.invertor import Invertor
13
14PR_FIT_LABEL       = "P_{fit}(r)"
15PR_LOADED_LABEL    = "P_{loaded}(r)"
16IQ_DATA_LABEL      = "I_{obs}(q)"
17IQ_FIT_LABEL       = "I_{fit}(q)"
18IQ_SMEARED_LABEL   = "I_{smeared}(q)"
19
20import wx.lib
21(NewPrFileEvent, EVT_PR_FILE) = wx.lib.newevent.NewEvent()
22
23
24class Plugin:
25   
26    DEFAULT_ALPHA = 0.0001
27    DEFAULT_NFUNC = 10
28    DEFAULT_DMAX  = 140.0
29   
30    def __init__(self):
31        ## Plug-in name
32        self.sub_menu = "Pr inversion"
33       
34        ## Reference to the parent window
35        self.parent = None
36       
37        ## Simulation window manager
38        self.simview = None
39       
40        ## List of panels for the simulation perspective (names)
41        self.perspective = []
42       
43        ## State data
44        self.alpha      = self.DEFAULT_ALPHA
45        self.nfunc      = self.DEFAULT_NFUNC
46        self.max_length = self.DEFAULT_DMAX
47        self.q_min      = None
48        self.q_max      = None
49        self.has_bck    = False
50        self.slit_height = 0
51        self.slit_width  = 0
52        ## Remember last plottable processed
53        self.last_data  = "sphere_60_q0_2.txt"
54        ## Time elapsed for last computation [sec]
55        # Start with a good default
56        self.elapsed = 0.022
57        self.iq_data_shown = False
58       
59        ## Current invertor
60        self.invertor    = None
61        self.pr          = None
62        self.pr_estimate = None
63        ## Calculation thread
64        self.calc_thread = None
65        ## Estimation thread
66        self.estimation_thread = None
67        ## Result panel
68        self.control_panel = None
69        ## Currently views plottable
70        self.current_plottable = None
71        ## Number of P(r) points to display on the output plot
72        self._pr_npts = 51
73        ## Flag to let the plug-in know that it is running standalone
74        self.standalone = True
75       
76        # Log startup
77        logging.info("Pr(r) plug-in started")
78       
79       
80
81    def populate_menu(self, id, owner):
82        """
83            Create a menu for the plug-in
84        """
85        return []
86   
87    def help(self, evt):
88        """
89            Show a general help dialog.
90            TODO: replace the text with a nice image
91        """
92        from inversion_panel import HelpDialog
93        dialog = HelpDialog(None, -1)
94        if dialog.ShowModal() == wx.ID_OK:
95            dialog.Destroy()
96        else:
97            dialog.Destroy()
98   
99    def _fit_pr(self, evt):
100        from sans.pr.invertor import Invertor
101        import numpy
102        import pylab
103        import math
104        from sans.guicomm.events import NewPlotEvent           
105        from sans.guitools.plottables import Data1D, Theory1D
106       
107        # Generate P(r) for sphere
108        radius = 60.0
109        d_max  = 2*radius
110       
111       
112        r = pylab.arange(0.01, d_max, d_max/51.0)
113        M = len(r)
114        y = numpy.zeros(M)
115        pr_err = numpy.zeros(M)
116       
117        sum = 0.0
118        for j in range(M):
119            value = self.pr_theory(r[j], radius)
120            sum += value
121            y[j] = value
122            pr_err[j] = math.sqrt(y[j])
123
124           
125        y = y/sum*d_max/len(r)
126
127
128
129        # Perform fit
130        pr = Invertor()
131        pr.d_max = d_max
132        pr.alpha = 0
133        pr.x = r
134        pr.y = y
135        pr.err = pr_err
136        out, cov = pr.pr_fit()
137        for i in range(len(out)):
138            print "%g +- %g" % (out[i], math.sqrt(cov[i][i]))
139
140
141        # Show input P(r)
142        new_plot = Data1D(pr.x, pr.y, dy=pr.err)
143        new_plot.name = "P_{obs}(r)"
144        new_plot.xaxis("\\rm{r}", 'A')
145        new_plot.yaxis("\\rm{P(r)} ","cm^{-3}")
146        wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, title="Pr"))
147
148        # Show P(r) fit
149        self.show_pr(out, pr)
150       
151        # Show I(q) fit
152        q = pylab.arange(0.001, 0.1, 0.01/51.0)
153        self.show_iq(out, pr, q)
154       
155       
156    def show_shpere(self, x, radius=70.0, x_range=70.0):
157        import numpy
158        import pylab
159        import math
160        from sans.guicomm.events import NewPlotEvent           
161        from sans.guitools.plottables import Data1D, Theory1D
162        # Show P(r)
163        y_true = numpy.zeros(len(x))
164
165        sum_true = 0.0
166        for i in range(len(x)):
167            y_true[i] = self.pr_theory(x[i], radius)           
168            sum_true += y_true[i]
169           
170        y_true = y_true/sum_true*x_range/len(x)
171       
172        # Show the theory P(r)
173        new_plot = Theory1D(x, y_true)
174        new_plot.name = "P_{true}(r)"
175        new_plot.xaxis("\\rm{r}", 'A')
176        new_plot.yaxis("\\rm{P(r)} ","cm^{-3}")
177       
178       
179        #Put this call in plottables/guitools   
180        wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, title="Sphere P(r)"))
181       
182    def get_npts(self):
183        """
184            Returns the number of points in the I(q) data
185        """
186        try:
187            return len(self.pr.x)
188        except:
189            return 0
190       
191    def show_iq(self, out, pr, q=None):
192        import numpy
193        import pylab
194        import math
195        from sans.guicomm.events import NewPlotEvent           
196        from sans.guitools.plottables import Data1D, Theory1D
197
198        qtemp = pr.x
199        if not q==None:
200            qtemp = q
201
202        # Make a plot
203        maxq = -1
204        for q_i in qtemp:
205            if q_i>maxq:
206                maxq=q_i
207               
208        minq = 0.001
209       
210        # Check for user min/max
211        if not pr.q_min==None:
212            minq = pr.q_min
213        if not pr.q_max==None:
214            maxq = pr.q_max
215               
216        x = pylab.arange(minq, maxq, maxq/301.0)
217        y = numpy.zeros(len(x))
218        err = numpy.zeros(len(x))
219        for i in range(len(x)):
220            value = pr.iq(out, x[i])
221            y[i] = value
222            try:
223                err[i] = math.sqrt(math.fabs(value))
224            except:
225                err[i] = 1.0
226                print "Error getting error", value, x[i]
227               
228        new_plot = Theory1D(x, y)
229        new_plot.name = IQ_FIT_LABEL
230        new_plot.xaxis("\\rm{Q}", 'A^{-1}')
231        new_plot.yaxis("\\rm{Intensity} ","cm^{-1}")
232        #new_plot.group_id = "test group"
233        wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, title="I(q)"))
234       
235        # If we have used slit smearing, plot the smeared I(q) too
236        if pr.slit_width>0 or pr.slit_height>0:
237            x = pylab.arange(minq, maxq, maxq/301.0)
238            y = numpy.zeros(len(x))
239            err = numpy.zeros(len(x))
240            for i in range(len(x)):
241                value = pr.iq_smeared(out, x[i])
242                y[i] = value
243                try:
244                    err[i] = math.sqrt(math.fabs(value))
245                except:
246                    err[i] = 1.0
247                    print "Error getting error", value, x[i]
248                   
249            new_plot = Theory1D(x, y)
250            new_plot.name = IQ_SMEARED_LABEL
251            new_plot.xaxis("\\rm{Q}", 'A^{-1}')
252            new_plot.yaxis("\\rm{Intensity} ","cm^{-1}")
253            #new_plot.group_id = "test group"
254            wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, title="I(q)"))
255       
256       
257    def _on_pr_npts(self, evt):
258        """
259            Redisplay P(r) with a different number of points
260        """   
261        from inversion_panel import PrDistDialog
262        dialog = PrDistDialog(None, -1)
263        dialog.set_content(self._pr_npts)
264        if dialog.ShowModal() == wx.ID_OK:
265            self._pr_npts= dialog.get_content()
266            dialog.Destroy()
267            self.show_pr(self.pr.out, self.pr, self.pr.cov)
268        else:
269            dialog.Destroy()
270       
271       
272    def show_pr(self, out, pr, cov=None):
273        import numpy
274        import pylab
275        import math
276        from sans.guicomm.events import NewPlotEvent           
277        from sans.guitools.plottables import Data1D, Theory1D
278       
279        # Show P(r)
280        x = pylab.arange(0.0, pr.d_max, pr.d_max/self._pr_npts)
281   
282        y = numpy.zeros(len(x))
283        dy = numpy.zeros(len(x))
284        y_true = numpy.zeros(len(x))
285
286        sum = 0.0
287        cov2 = numpy.ascontiguousarray(cov)
288       
289        for i in range(len(x)):
290            if cov2==None:
291                value = pr.pr(out, x[i])
292            else:
293                (value, dy[i]) = pr.pr_err(out, cov2, x[i])
294            sum += value*pr.d_max/len(x)
295            y[i] = value
296           
297        y = y/sum
298        dy = dy/sum
299       
300        if cov2==None:
301            new_plot = Theory1D(x, y)
302        else:
303            new_plot = Data1D(x, y, dy=dy)
304        new_plot.name = "P_{fit}(r)"
305        new_plot.xaxis("\\rm{r}", 'A')
306        new_plot.yaxis("\\rm{P(r)} ","cm^{-3}")
307           
308        wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, title="P(r) fit"))
309       
310        return x, pr.d_max
311       
312       
313    def choose_file(self):
314        """
315       
316        """
317        #TODO: this should be in a common module
318        return self.parent.choose_file()
319               
320    def load(self, path = "sphere_60_q0_2.txt"):
321        import numpy, math, sys
322        # Read the data from the data file
323        data_x   = numpy.zeros(0)
324        data_y   = numpy.zeros(0)
325        data_err = numpy.zeros(0)
326        scale    = None
327        min_err  = 0.0
328        if not path == None:
329            input_f = open(path,'r')
330            buff    = input_f.read()
331            lines   = buff.split('\n')
332            for line in lines:
333                try:
334                    toks = line.split()
335                    x = float(toks[0])
336                    y = float(toks[1])
337                    if len(toks)>2:
338                        err = float(toks[2])
339                    else:
340                        if scale==None:
341                            scale = 0.05*math.sqrt(y)
342                            #scale = 0.05/math.sqrt(y)
343                            min_err = 0.01*y
344                        err = scale*math.sqrt(y)+min_err
345                        #err = 0
346                       
347                    data_x = numpy.append(data_x, x)
348                    data_y = numpy.append(data_y, y)
349                    data_err = numpy.append(data_err, err)
350                except:
351                    pass
352                   
353        return data_x, data_y, data_err     
354       
355    def pr_theory(self, r, R):
356        """
357           
358        """
359        if r<=2*R:
360            return 12.0* ((0.5*r/R)**2) * ((1.0-0.5*r/R)**2) * ( 2.0 + 0.5*r/R )
361        else:
362            return 0.0
363
364    def get_context_menu(self, graph=None):
365        """
366            Get the context menu items available for P(r)
367            @param graph: the Graph object to which we attach the context menu
368            @return: a list of menu items with call-back function
369        """
370        # Look whether this Graph contains P(r) data
371        #if graph.selected_plottable==IQ_DATA_LABEL:
372        for item in graph.plottables:
373            if item.name==PR_FIT_LABEL:
374                return [["Add P(r) data", "Load a data file and display it on this plot", self._on_add_data],
375                       ["Change number of P(r) points", "Change the number of points on the P(r) output", self._on_pr_npts]]
376
377            elif item.name==graph.selected_plottable:
378                return [["Compute P(r)", "Compute P(r) from distribution", self._on_context_inversion]]     
379               
380        return []
381
382    def _on_add_data(self, evt):
383        """
384            Add a data curve to the plot
385            WARNING: this will be removed once guiframe.plotting has its full functionality
386        """
387        path = self.choose_file()
388        if path==None:
389            return
390       
391        x, y, err = self.parent.load_ascii_1D(path)
392       
393        #new_plot = Data1D(x, y, dy=err)
394        new_plot = Theory1D(x, y)
395        new_plot.name = "P_{loaded}(r)"
396        new_plot.xaxis("\\rm{r}", 'A')
397        new_plot.yaxis("\\rm{P(r)} ","cm^{-3}")
398           
399        wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, title="P(r) fit"))
400       
401       
402
403    def start_thread(self):
404        from pr_thread import CalcPr
405        from copy import deepcopy
406       
407        # If a thread is already started, stop it
408        if self.calc_thread != None and self.calc_thread.isrunning():
409            self.calc_thread.stop()
410               
411        pr = self.pr.clone()
412        self.calc_thread = CalcPr(pr, self.nfunc, error_func=self._thread_error, completefn=self._completed, updatefn=None)
413        self.calc_thread.queue()
414        self.calc_thread.ready(2.5)
415   
416    def _thread_error(self, error):
417        wx.PostEvent(self.parent, StatusEvent(status=error))
418   
419    def _estimate_completed(self, alpha, message, elapsed):
420        """
421            Parameter estimation completed,
422            display the results to the user
423            @param alpha: estimated best alpha
424            @param elapsed: computation time
425        """
426        # Save useful info
427        self.elapsed = elapsed
428        self.control_panel.alpha_estimate = alpha
429        if not message==None:
430            wx.PostEvent(self.parent, StatusEvent(status=str(message)))
431           
432        self.perform_estimateNT()
433   
434
435   
436    def _estimateNT_completed(self, nterms, alpha, message, elapsed):
437        """
438            Parameter estimation completed,
439            display the results to the user
440            @param alpha: estimated best alpha
441            @param nterms: estimated number of terms
442            @param elapsed: computation time
443        """
444        # Save useful info
445        self.elapsed = elapsed
446        self.control_panel.nterms_estimate = nterms
447        self.control_panel.alpha_estimate = alpha
448        if not message==None:
449            wx.PostEvent(self.parent, StatusEvent(status=str(message)))
450   
451    def _completed(self, out, cov, pr, elapsed):
452        """
453            Method called with the results when the inversion
454            is done
455           
456            @param out: output coefficient for the base functions
457            @param cov: covariance matrix
458            @param pr: Invertor instance
459            @param elapsed: time spent computing
460        """
461        from copy import deepcopy
462        # Save useful info
463        self.elapsed = elapsed
464        # Save Pr invertor
465        self.pr = pr
466       
467        #message = "Computation completed in %g seconds [chi2=%g]" % (elapsed, pr.chi2)
468        #wx.PostEvent(self.parent, StatusEvent(status=message))
469
470        cov = numpy.ascontiguousarray(cov)
471
472        # Show result on control panel
473        self.control_panel.chi2 = pr.chi2
474        self.control_panel.elapsed = elapsed
475        self.control_panel.oscillation = pr.oscillations(out)
476        #print "OSCILL", pr.oscillations(out)
477        #print "PEAKS:", pr.get_peaks(out)
478        self.control_panel.positive = pr.get_positive(out)
479        self.control_panel.pos_err  = pr.get_pos_err(out, cov)
480        self.control_panel.rg = pr.rg(out)
481        self.control_panel.iq0 = pr.iq0(out)
482        self.control_panel.bck = pr.background
483       
484        for i in range(len(out)):
485            try:
486                print "%d: %g +- %g" % (i, out[i], math.sqrt(math.fabs(cov[i][i])))
487            except: 
488                print sys.exc_value
489                print "%d: %g +- ?" % (i, out[i])       
490       
491        # Make a plot of I(q) data
492        if False:
493            new_plot = Data1D(self.pr.x, self.pr.y, dy=self.pr.err)
494            new_plot.name = "I_{obs}(q)"
495            new_plot.xaxis("\\rm{Q}", 'A^{-1}')
496            new_plot.yaxis("\\rm{Intensity} ","cm^{-1}")
497            #new_plot.group_id = "test group"
498            wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, title="Iq"))
499               
500        # Show I(q) fit
501        self.show_iq(out, self.pr)
502       
503        # Show P(r) fit
504        x_values, x_range = self.show_pr(out, self.pr, cov) 
505       
506        # Popup result panel
507        #result_panel = InversionResults(self.parent, -1, style=wx.RAISED_BORDER)
508       
509    def show_data(self, path=None, reset=False):
510        """
511            Show data read from a file
512            @param path: file path
513            @param reset: if True all other plottables will be cleared
514        """
515       
516       
517        if not path==None:
518            self._create_file_pr(path) 
519             
520        # Make a plot of I(q) data
521        new_plot = Data1D(self.pr.x, self.pr.y, dy=self.pr.err)
522        new_plot.name = "I_{obs}(q)"
523        new_plot.xaxis("\\rm{Q}", 'A^{-1}')
524        new_plot.yaxis("\\rm{Intensity} ","cm^{-1}")
525        new_plot.interactive = True
526        #new_plot.group_id = "test group"
527        wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, title="I(q)", reset=reset))
528       
529        # Get Q range
530        self.control_panel.q_min = self.pr.x.min()
531        self.control_panel.q_max = self.pr.x.max()
532           
533
534       
535    def setup_plot_inversion(self, alpha, nfunc, d_max, q_min=None, q_max=None, 
536                             bck=False, height=0, width=0):
537        self.alpha = alpha
538        self.nfunc = nfunc
539        self.max_length = d_max
540        self.q_min = q_min
541        self.q_max = q_max
542        self.has_bck = bck
543        self.slit_height = height
544        self.slit_width  = width
545       
546        try:
547            pr = self._create_plot_pr()
548            if not pr==None:
549                self.pr = pr
550                self.perform_inversion()
551        except:
552            wx.PostEvent(self.parent, StatusEvent(status=sys.exc_value))
553
554    def estimate_plot_inversion(self, alpha, nfunc, d_max, q_min=None, q_max=None, 
555                                bck=False, height=0, width=0):
556        self.alpha = alpha
557        self.nfunc = nfunc
558        self.max_length = d_max
559        self.q_min = q_min
560        self.q_max = q_max
561        self.has_bck = bck
562        self.slit_height = height
563        self.slit_width  = width
564       
565        try:
566            pr = self._create_plot_pr()
567            if not pr==None:
568                self.pr = pr
569                self.perform_estimate()
570        except:
571            wx.PostEvent(self.parent, StatusEvent(status=sys.exc_value))           
572
573    def _create_plot_pr(self, estimate=False):
574        """
575            Create and prepare invertor instance from
576            a plottable data set.
577            @param path: path of the file to read in
578        """
579        # Get the data from the chosen data set and perform inversion
580        pr = Invertor()
581        pr.d_max = self.max_length
582        pr.alpha = self.alpha
583        pr.q_min = self.q_min
584        pr.q_max = self.q_max
585        pr.x = self.current_plottable.x
586        pr.y = self.current_plottable.y
587        pr.has_bck = self.has_bck
588        pr.slit_height = self.slit_height
589        pr.slit_width = self.slit_width
590       
591        # Fill in errors if none were provided
592        if self.current_plottable.dy == None:
593            print "no error", self.current_plottable.name
594            y = numpy.zeros(len(pr.y))
595            for i in range(len(pr.y)):
596                y[i] = math.sqrt(pr.y[i])
597            pr.err = y
598        else:
599            pr.err = self.current_plottable.dy
600       
601        #self.pr = pr
602        return pr
603
604         
605    def setup_file_inversion(self, alpha, nfunc, d_max, path, q_min=None, q_max=None, 
606                             bck=False, height=0, width=0):
607        self.alpha = alpha
608        self.nfunc = nfunc
609        self.max_length = d_max
610        self.q_min = q_min
611        self.q_max = q_max
612        self.has_bck = bck
613        self.slit_height = height
614        self.slit_width  = width
615       
616        try:
617            pr = self._create_file_pr(path)
618            if not pr==None:
619                self.pr = pr
620                self.perform_inversion()
621        except:
622            wx.PostEvent(self.parent, StatusEvent(status=sys.exc_value))
623         
624    def estimate_file_inversion(self, alpha, nfunc, d_max, path, q_min=None, q_max=None, 
625                                bck=False, height=0, width=0):
626        self.alpha = alpha
627        self.nfunc = nfunc
628        self.max_length = d_max
629        self.q_min = q_min
630        self.q_max = q_max
631        self.has_bck = bck
632        self.slit_height = height
633        self.slit_width  = width
634       
635        try:
636            pr = self._create_file_pr(path)
637            if not pr==None:
638                self.pr = pr
639                self.perform_estimate()
640        except:
641            wx.PostEvent(self.parent, StatusEvent(status=sys.exc_value))
642               
643         
644    def _create_file_pr(self, path):
645        """
646            Create and prepare invertor instance from
647            a file data set.
648            @param path: path of the file to read in
649        """
650        # Load data
651        if os.path.isfile(path):
652            x, y, err = self.load(path)
653           
654            # Get the data from the chosen data set and perform inversion
655            pr = Invertor()
656            pr.d_max = self.max_length
657            pr.alpha = self.alpha
658            pr.q_min = self.q_min
659            pr.q_max = self.q_max
660            pr.x = x
661            pr.y = y
662            pr.err = err
663            pr.has_bck = self.has_bck
664            pr.slit_height = self.slit_height
665            pr.slit_width = self.slit_width
666            return pr
667            #self.pr = pr
668            #return True
669        #return False
670        return None
671       
672    def perform_estimate(self):
673        from pr_thread import EstimatePr
674        from copy import deepcopy
675       
676        wx.PostEvent(self.parent, StatusEvent(status=''))
677        # If a thread is already started, stop it
678        if self.estimation_thread != None and self.estimation_thread.isrunning():
679            self.estimation_thread.stop()
680               
681        pr = self.pr.clone()
682        self.estimation_thread = EstimatePr(pr, self.nfunc, error_func=self._thread_error, 
683                                            completefn = self._estimate_completed, 
684                                            updatefn   = None)
685        self.estimation_thread.queue()
686        self.estimation_thread.ready(2.5)
687   
688    def perform_estimateNT(self):
689        from pr_thread import EstimateNT
690        from copy import deepcopy
691       
692        wx.PostEvent(self.parent, StatusEvent(status=''))
693        # If a thread is already started, stop it
694        if self.estimation_thread != None and self.estimation_thread.isrunning():
695            self.estimation_thread.stop()
696               
697        pr = self.pr.clone()
698        # Skip the slit settings for the estimation
699        # It slows down the application and it doesn't change the estimates
700        pr.slit_height = 0.0
701        pr.slit_width  = 0.0
702        self.estimation_thread = EstimateNT(pr, self.nfunc, error_func=self._thread_error, 
703                                            completefn = self._estimateNT_completed, 
704                                            updatefn   = None)
705        self.estimation_thread.queue()
706        self.estimation_thread.ready(2.5)
707       
708    def perform_inversion(self):
709       
710        # Time estimate
711        #estimated = self.elapsed*self.nfunc**2
712        #message = "Computation time may take up to %g seconds" % self.elapsed
713        #wx.PostEvent(self.parent, StatusEvent(status=message))
714       
715        # Start inversion thread
716        self.start_thread()
717        return
718       
719        out, cov = self.pr.lstsq(self.nfunc)
720       
721        # Save useful info
722        self.elapsed = self.pr.elapsed
723       
724        for i in range(len(out)):
725            try:
726                print "%d: %g +- %g" % (i, out[i], math.sqrt(math.fabs(cov[i][i])))
727            except: 
728                print "%d: %g +- ?" % (i, out[i])       
729       
730       
731       
732        # Make a plot of I(q) data
733        new_plot = Data1D(self.pr.x, self.pr.y, dy=self.pr.err)
734        new_plot.name = "I_{obs}(q)"
735        new_plot.xaxis("\\rm{Q}", 'A^{-1}')
736        new_plot.yaxis("\\rm{Intensity} ","cm^{-1}")
737        wx.PostEvent(self.parent, NewPlotEvent(plot=new_plot, title="Iq"))
738               
739        # Show I(q) fit
740        self.show_iq(out, self.pr)
741       
742        # Show P(r) fit
743        x_values, x_range = self.show_pr(out, self.pr, cov=cov)
744       
745       
746         
747    def _on_context_inversion(self, event):
748        panel = event.GetEventObject()
749
750        from inversion_panel import InversionDlg
751       
752        # If we have more than one displayed plot, make the user choose
753        if len(panel.plots)>1 and panel.graph.selected_plottable in panel.plots:
754            dataset = panel.graph.selected_plottable
755            if False:
756                dialog = InversionDlg(None, -1, "P(r) Inversion", panel.plots, pars=False)
757                dialog.set_content(self.last_data, self.nfunc, self.alpha, self.max_length)
758                if dialog.ShowModal() == wx.ID_OK:
759                    dataset = dialog.get_content()
760                    dialog.Destroy()
761                else:
762                    dialog.Destroy()
763                    return
764        elif len(panel.plots)==1:
765            dataset = panel.plots.keys()[0]
766        else:
767            print "Error: No data is available"
768            return
769       
770        # Store a reference to the current plottable
771        # If we have a suggested value, use it.
772        try:
773            estimate = float(self.control_panel.alpha_estimate)
774            self.control_panel.alpha = estimate
775        except:
776            self.control_panel.alpha = self.alpha
777            print "No estimate yet"
778            pass
779        try:
780            estimate = int(self.control_panel.nterms_estimate)
781            self.control_panel.nfunc = estimate
782        except:
783            self.control_panel.nfunc = self.nfunc
784            print "No estimate yet"
785            pass
786       
787        self.current_plottable = panel.plots[dataset]
788        self.control_panel.plotname = dataset
789        #self.control_panel.nfunc = self.nfunc
790        self.control_panel.d_max = self.max_length
791        self.parent.set_perspective(self.perspective)
792        self.control_panel._on_invert(None)
793           
794    def get_panels(self, parent):
795        """
796            Create and return a list of panel objects
797        """
798        from inversion_panel import InversionControl
799       
800        self.parent = parent
801        self.control_panel = InversionControl(self.parent, -1, 
802                                              style=wx.RAISED_BORDER,
803                                              standalone=self.standalone)
804        self.control_panel.set_manager(self)
805        self.control_panel.nfunc = self.nfunc
806        self.control_panel.d_max = self.max_length
807        self.control_panel.alpha = self.alpha
808       
809        self.perspective = []
810        self.perspective.append(self.control_panel.window_name)
811       
812        self.parent.Bind(EVT_PR_FILE, self._on_new_file)
813       
814        return [self.control_panel]
815   
816    def _on_new_file(self, evt):
817        """
818            Called when the application manager posted an
819            EVT_PR_FILE event. Just prompt the control
820            panel to load a new data file.
821        """
822        self.control_panel._change_file(None)
823   
824    def get_perspective(self):
825        """
826            Get the list of panel names for this perspective
827        """
828        return self.perspective
829   
830    def on_perspective(self, event):
831        """
832            Call back function for the perspective menu item.
833            We notify the parent window that the perspective
834            has changed.
835        """
836        self.parent.set_perspective(self.perspective)
837   
838    def post_init(self):
839        """
840            Post initialization call back to close the loose ends
841            [Somehow openGL needs this call]
842        """
843        self.parent.set_perspective(self.perspective)
844 
845if __name__ == "__main__":
846    i = Plugin()
847    print i.perform_estimateNT()
848   
849   
850   
851   
Note: See TracBrowser for help on using the repository browser.