Changeset 4403 for trunk


Ignore:
Timestamp:
Apr 18, 2020 10:30:23 AM (3 years ago)
Author:
toby
Message:

add new incid. beam mono convolutor to FPA; refactor FPA GUI

Location:
trunk
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/GSASIIfpaGUI.py

    r4365 r4403  
    1818'''
    1919from __future__ import division, print_function
    20 import wx
    2120import os.path
    2221import numpy as np
     22
     23import wx
     24import wx.lib.scrolledpanel as wxscroll
    2325
    2426import NIST_profile as FP
     
    6264    ('tube-tails_rel-I', 0.001,'Tube tails fractional intensity (no units)'),
    6365    ]
    64 '''FPA dict entries used in :func:`MakeTopasFPASizer`. Tuple contains
     66'''FPA dict entries used in :func:`FillParmSizer`. Tuple contains
    6567a dict key, a default value and a description. These are the parameters
    6668needed for all Bragg Brentano instruments
     
    6971BBPointDetector = [
    7072    ('receiving_slit_width', 0.2, 'Width of receiving slit (mm)'),]
    71 '''Additional FPA dict entries used in :func:`MakeTopasFPASizer`
     73'''Additional FPA dict entries used in :func:`FillParmSizer`
    7274needed for Bragg Brentano instruments with point detectors.
    7375'''
     
    7678    ('lpsd_th2_angular_range', 3.0, 'Angular range observed by PSD (degrees 2Theta)'),
    7779    ('lpsd_equitorial_divergence', 0.1, 'Equatorial divergence of the primary beam (degrees)'),]
    78 '''Additional FPA dict entries used in :func:`MakeTopasFPASizer`
     80'''Additional FPA dict entries used in :func:`FillParmSizer`
    7981needed for Bragg Brentano instruments with linear (1-D) PSD detectors.
    8082'''
    8183
    82 Citation = '''MH Mendenhall, K Mullen && JP Cline. (2015) J. Res. of NIST 120, 223-251. doi:10.6028/jres.120.014.
    83 '''
    84    
     84IBmonoParms = [
     85    ('src_mono_mm',119,'Distance from xray line source to monochromator crystal (mm)'),
     86    ('focus_mono_mm',217,'Distance from monochromator crystal to focus slit (mm)'),
     87    ('passband_mistune',-0.145,'Offset from the tuning of the IBM to the center of the reference line of the spectrum, in units of its bandwidth'),
     88    ('mono_src_proj_mn',51,'Projection width of line-focus xray source on the monochromator along beam direction (microns), sets bandwidth'),
     89    ('passband_shoulder',.087,'Width of transition region from flat top to tails, in units of the bandwidth'),
     90    ('two_theta_mono',27.27,'The full diffraction angle of the IBM crystal, e.g. double 2theta-Bragg for the mono (deg)')]
     91'''Additional FPA dict entries used in :func:`FillParmSizer`, needed for Incident Beam Monochromator
     92'''
     93   
     94Citation = '''MH Mendenhall, K Mullen && JP Cline, 2015, J. Res. of NIST, 120, p223. DOI: 10.6028/jres.120.014
     95
     96Incident Beam Mono: MH Mendenhall, D. Black && JP Cline, J. Appl. Cryst., 2019, 52, p1087. DOI: 10.1107/S1600576719010951
     97'''
     98
     99IBmono = False
     100'''set to True if an incident beam monochromator is in use
     101'''
     102DetMode = 'BBpoint'
     103'''The type of detector, either 'BBpoint' for Bragg-Brentano point detector or
     104      or 'BBPSD' (linear) position sensitive detector
     105'''
     106
    85107def SetCu2Wave():
    86108    '''Set the parameters to the two-line Cu K alpha 1+2 spectrum
     
    91113SetCu2Wave() # use these as default
    92114
    93 def MakeTopasFPASizer(G2frame,FPdlg,mode,SetButtonStatus):
     115
     116def FillParmSizer():
     117    '''Create a list of input items for the parameter section of the
     118    input window, sets default values when not set and displays them
     119    in the scrolledpanel prmPnl.
     120    '''
     121    prmSizer = prmPnl.GetSizer()
     122    prmSizer.Clear(True)
     123    if DetMode == 'BBpoint':
     124        itemList = BraggBrentanoParms+BBPointDetector
     125    elif DetMode == 'BBPSD':
     126        itemList = BraggBrentanoParms+BBPSDDetector
     127    else:
     128        raise Exception('Unknown DetMode in FillParmSizer: '+DetMode)
     129    if IBmono:
     130         itemList += IBmonoParms   
     131    text = wx.StaticText(prmPnl,wx.ID_ANY,'label',style=wx.ALIGN_CENTER,
     132                size=(170,-1)) # make just a bit bigger than largest item in column
     133    text.SetBackgroundColour(wx.WHITE)
     134    prmSizer.Add(text,0,wx.EXPAND)
     135    text = wx.StaticText(prmPnl,wx.ID_ANY,'value',style=wx.ALIGN_CENTER)
     136    text.SetBackgroundColour(wx.WHITE)
     137    prmSizer.Add(text,0,wx.EXPAND)
     138    text = wx.StaticText(prmPnl,wx.ID_ANY,'explanation',style=wx.ALIGN_CENTER)
     139    text.SetBackgroundColour(wx.WHITE)
     140    prmSizer.Add(text,0,wx.EXPAND)
     141    for lbl,defVal,text in itemList:
     142        prmSizer.Add(wx.StaticText(prmPnl,wx.ID_ANY,lbl),1,wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL,1)
     143        if lbl not in parmDict: parmDict[lbl] = defVal
     144        ctrl = G2G.ValidatedTxtCtrl(prmPnl,parmDict,lbl,size=(70,-1))
     145        prmSizer.Add(ctrl,1,wx.ALL|wx.ALIGN_CENTER_VERTICAL,1)
     146        txt = wx.StaticText(prmPnl,wx.ID_ANY,text,size=(400,-1))
     147        txt.Wrap(380)
     148        prmSizer.Add(txt)
     149    px1,py = prmSizer.GetSize()
     150    prmSizer.Layout()
     151    FPdlg = prmPnl.GetParent()
     152    FPdlg.SendSizeEvent()
     153       
     154def MakeTopasFPASizer(G2frame,FPdlg,SetButtonStatus):
    94155    '''Create a GUI with parameters for the NIST XRD Fundamental Parameters Code.
    95156    Parameter input is modeled after Topas input parameters.
    96157
     158    :param wx.Frame G2frame: main GSAS-II window
    97159    :param wx.Window FPdlg: Frame or Dialog where GUI will appear
    98     :param str mode: either 'BBpoint' or 'BBPSD' for Bragg-Brentano point detector or
    99       (linear) position sensitive detector
    100     :param dict parmDict: dict to place parameters. If empty, default values from
    101       globals BraggBrentanoParms, BBPointDetector & BBPSDDetector will be placed in
    102       the array.
     160    :param SetButtonStatus: a callback function to call to see what buttons in
     161      this windows can be enabled. Called with done=True to trigger closing
     162      the parent window as well.
    103163    :returns: a sizer with the GUI controls
    104  
    105164    '''
    106165    def _onOK(event):
     
    113172    def _onAddWave(event):
    114173        parmDict['numWave'] += 1
    115         wx.CallAfter(MakeTopasFPASizer,G2frame,FPdlg,mode,SetButtonStatus)
     174        wx.CallAfter(MakeTopasFPASizer,G2frame,FPdlg,SetButtonStatus)
    116175    def _onRemWave(event):
    117176        parmDict['numWave'] -= 1
    118         wx.CallAfter(MakeTopasFPASizer,G2frame,FPdlg,mode,SetButtonStatus)
     177        wx.CallAfter(MakeTopasFPASizer,G2frame,FPdlg,SetButtonStatus)
    119178    def _onSetCu5Wave(event):
    120179        parmDict['wave'] = {i:v for i,v in enumerate((1.534753,1.540596,1.541058,1.54441,1.544721))}
     
    122181        parmDict['lwidth'] = {i:v for i,v in enumerate((3.6854, 0.437, 0.6, 0.52, 0.62))}
    123182        parmDict['numWave'] = 5
    124         wx.CallAfter(MakeTopasFPASizer,G2frame,FPdlg,mode,SetButtonStatus)
     183        wx.CallAfter(MakeTopasFPASizer,G2frame,FPdlg,SetButtonStatus)
    125184    def _onSetCu2Wave(event):
    126185        SetCu2Wave()
    127186        parmDict['numWave'] = 2
    128         wx.CallAfter(MakeTopasFPASizer,G2frame,FPdlg,mode,SetButtonStatus)
    129     def _onSetPoint(event):
    130         wx.CallAfter(MakeTopasFPASizer,G2frame,FPdlg,'BBpoint',SetButtonStatus)
    131     def _onSetPSD(event):
    132         wx.CallAfter(MakeTopasFPASizer,G2frame,FPdlg,'BBPSD',SetButtonStatus)
     187        wx.CallAfter(MakeTopasFPASizer,G2frame,FPdlg,SetButtonStatus)
     188    def _onSetDetBtn(event):
     189        global DetMode
     190        if detBtn1.GetValue():
     191            DetMode = 'BBpoint'
     192            wx.CallAfter(FillParmSizer)
     193        else:
     194            DetMode = 'BBPSD'
     195            wx.CallAfter(FillParmSizer)
     196    def _onSetMonoBtn(event):
     197        global IBmono
     198        IBmono = not monoBtn1.GetValue()
     199        wx.CallAfter(FillParmSizer)
    133200    def PlotTopasFPA(event):
    134201        XferFPAsettings(parmDict)
     
    168235
    169236    if FPdlg.GetSizer(): FPdlg.GetSizer().Clear(True)
    170     numWave = parmDict['numWave']
    171     if mode == 'BBpoint':
    172         itemList = BraggBrentanoParms+BBPointDetector
    173     elif mode == 'BBPSD':
    174         itemList = BraggBrentanoParms+BBPSDDetector
    175     else:
    176         raise Exception('Unknown mode in MakeTopasFPASizer: '+mode)
    177    
     237    numWave = parmDict['numWave']   
    178238    MainSizer = wx.BoxSizer(wx.VERTICAL)
    179239    MainSizer.Add((-1,5))
     
    195255    MainSizer.Add((-1,5))
    196256    btnsizer = wx.BoxSizer(wx.HORIZONTAL)
    197     btn = wx.Button(FPdlg, wx.ID_ANY,'Add col')
     257    btn = wx.Button(FPdlg, wx.ID_ANY,'Add wave')
    198258    btnsizer.Add(btn)
    199259    btn.Bind(wx.EVT_BUTTON,_onAddWave)
    200     btn = wx.Button(FPdlg, wx.ID_ANY,'Remove col')
     260    btn = wx.Button(FPdlg, wx.ID_ANY,'Remove wave')
    201261    btnsizer.Add(btn)
    202262    btn.Bind(wx.EVT_BUTTON,_onRemWave)
     
    209269    MainSizer.Add(btnsizer, 0, wx.ALIGN_CENTER, 0)
    210270    MainSizer.Add((-1,5))
    211     btnsizer = wx.BoxSizer(wx.HORIZONTAL)
    212     btn = wx.Button(FPdlg, wx.ID_ANY,'Point Dect.')
    213     btn.Enable(not mode == 'BBpoint')
    214     btnsizer.Add(btn)
    215     btn.Bind(wx.EVT_BUTTON,_onSetPoint)
    216     btn = wx.Button(FPdlg, wx.ID_ANY,'PSD')
    217     btn.Enable(not mode == 'BBPSD')
    218     btnsizer.Add(btn)
    219     btn.Bind(wx.EVT_BUTTON,_onSetPSD)
     271   
     272    btnsizer = wx.GridBagSizer( 2, 5)
     273    btnsizer.Add( wx.StaticText(FPdlg, wx.ID_ANY, 'Detector type'),
     274                 (0,0), (2,1), wx.ALIGN_CENTER | wx.ALL, 5)   
     275    detBtn1 = wx.RadioButton(FPdlg,wx.ID_ANY,'Point',style=wx.RB_GROUP)
     276    detBtn1.SetValue(DetMode == 'BBpoint')
     277    btnsizer.Add(detBtn1, (0,1))
     278    detBtn1.Bind(wx.EVT_RADIOBUTTON,_onSetDetBtn)
     279    detBtn2 = wx.RadioButton(FPdlg,wx.ID_ANY,'PSD')
     280    detBtn2.SetValue(not DetMode == 'BBpoint')
     281    btnsizer.Add(detBtn2, (1,1))
     282    detBtn2.Bind(wx.EVT_RADIOBUTTON,_onSetDetBtn)
     283    btnsizer.Add( (40,-1), (0,2), (1,1), wx.ALIGN_CENTER | wx.ALL, 5)   
     284    btnsizer.Add( wx.StaticText(FPdlg, wx.ID_ANY, 'Incident Beam Mono'),
     285                 (0,3), (2,1), wx.ALIGN_CENTER | wx.ALL, 5)   
     286    monoBtn1 = wx.RadioButton(FPdlg,wx.ID_ANY,'No',style=wx.RB_GROUP)
     287    monoBtn1.SetValue(not IBmono)
     288    btnsizer.Add(monoBtn1, (0,4))
     289    monoBtn1.Bind(wx.EVT_RADIOBUTTON,_onSetMonoBtn)
     290    monoBtn2 = wx.RadioButton(FPdlg,wx.ID_ANY,'Yes')
     291    monoBtn2.SetValue(IBmono)
     292    btnsizer.Add(monoBtn2, (1,4))
     293    monoBtn2.Bind(wx.EVT_RADIOBUTTON,_onSetMonoBtn)
    220294    MainSizer.Add(btnsizer, 0, wx.ALIGN_CENTER, 0)
    221     MainSizer.Add((-1,5))
     295
     296    global prmPnl
     297    prmPnl = wxscroll.ScrolledPanel(FPdlg, wx.ID_ANY, #size=(200,200),
     298        style = wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER)
     299    prmSizer = wx.FlexGridSizer(cols=3,hgap=3,vgap=5)
     300    prmPnl.SetSizer(prmSizer)
     301    FillParmSizer()   
     302    MainSizer.Add(prmPnl,1,wx.EXPAND,1)
     303    prmPnl.SetAutoLayout(1)
     304    prmPnl.SetupScrolling()
    222305   
    223     prmSizer = wx.FlexGridSizer(cols=3,hgap=3,vgap=5)
    224     text = wx.StaticText(FPdlg,wx.ID_ANY,'label',style=wx.ALIGN_CENTER)
    225     text.SetBackgroundColour(wx.WHITE)
    226     prmSizer.Add(text,0,wx.EXPAND)
    227     text = wx.StaticText(FPdlg,wx.ID_ANY,'value',style=wx.ALIGN_CENTER)
    228     text.SetBackgroundColour(wx.WHITE)
    229     prmSizer.Add(text,0,wx.EXPAND)
    230     text = wx.StaticText(FPdlg,wx.ID_ANY,'explanation',style=wx.ALIGN_CENTER)
    231     text.SetBackgroundColour(wx.WHITE)
    232     prmSizer.Add(text,0,wx.EXPAND)
    233     for lbl,defVal,text in itemList:
    234         prmSizer.Add(wx.StaticText(FPdlg,wx.ID_ANY,lbl),1,wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL,1)
    235         if lbl not in parmDict: parmDict[lbl] = defVal
    236         ctrl = G2G.ValidatedTxtCtrl(FPdlg,parmDict,lbl,size=(70,-1))
    237         prmSizer.Add(ctrl,1,wx.ALL|wx.ALIGN_CENTER_VERTICAL,1)
    238         txt = wx.StaticText(FPdlg,wx.ID_ANY,text,size=(400,-1))
    239         txt.Wrap(380)
    240         prmSizer.Add(txt)
    241     MainSizer.Add(prmSizer)
    242     MainSizer.Add((-1,4),1,wx.EXPAND,1)
     306    MainSizer.Add((-1,4))
    243307    btnsizer = wx.BoxSizer(wx.HORIZONTAL)
    244308    btn = wx.Button(FPdlg, wx.ID_ANY, 'Plot peak')
     
    251315    btnsizer.Add(wx.StaticText(FPdlg,wx.ID_ANY,' deg.'))   
    252316    MainSizer.Add(btnsizer, 0, wx.ALIGN_CENTER, 0)
    253     MainSizer.Add((-1,4),1,wx.EXPAND,1)
     317    MainSizer.Add((-1,4))
    254318    btnsizer = wx.BoxSizer(wx.HORIZONTAL)
    255319    OKbtn = wx.Button(FPdlg, wx.ID_OK)
     
    259323    btnsizer.Add(Cbtn)
    260324    MainSizer.Add(btnsizer, 0, wx.ALIGN_CENTER, 0)
    261     MainSizer.Add((-1,4),1,wx.EXPAND,1)
     325    MainSizer.Add((-1,4))
    262326    # bindings for close of window
    263327    OKbtn.Bind(wx.EVT_BUTTON,_onOK)
     
    266330    MainSizer.Layout()
    267331    MainSizer.Fit(FPdlg)
    268     FPdlg.SetMinSize(FPdlg.GetSize())
    269     FPdlg.SendSizeEvent()
    270 
     332    # control window size
     333    px,py = prmSizer.GetSize()
     334    dx,dy = FPdlg.GetSize()
     335    FPdlg.SetMinSize((dx,dy+200)) # leave a min of 200 points for scroll panel   
     336    FPdlg.SetSize((max(dx,px+20),min(750,dy+py+30))) # 20 for scroll bar, 30 for a bit of room at bottom
     337   
    271338def XferFPAsettings(InpParms):
    272339    '''convert Topas-type parameters to SI units for NIST and place in a dict sorted
     
    290357                'crystallite_size_gauss' : 1.e-9 * InpParms.get('Size_G',1e6),
    291358                'crystallite_size_lor' : 1.e-9 * InpParms.get('Size_L',1e6)}
     359    if IBmono:
     360        NISTparms["emission"]['a_mono'] = InpParms['src_mono_mm'] * 10**-3
     361        NISTparms["emission"]['b_mono'] = InpParms['focus_mono_mm'] * 10**-3
     362        NISTparms["emission"]['ibm_source_width'] = InpParms['mono_src_proj_mn'] * 10**-6
     363        for i in  ('passband_mistune','passband_shoulder','two_theta_mono'):
     364            NISTparms["emission"][i] = InpParms[i]
    292365   
    293366    if InpParms['filament_length'] == InpParms['receiving_slit_length']: # workaround:
     
    355428      each convolution or compute the composite peak shape.
    356429    '''
    357     p=FP.FP_profile(anglemode="twotheta",
     430    if IBmono:
     431        p=FP.FP_windowed(anglemode="twotheta",
    358432                    output_gaussian_smoother_bins_sigma=1.0,
    359433                    oversampling=NISTparms.get('oversampling',10))
     434    else:
     435        p=FP.FP_profile(anglemode="twotheta",
     436                    output_gaussian_smoother_bins_sigma=1.0,
     437                    oversampling=NISTparms.get('oversampling',10))
     438       
    360439    p.debug_cache=False
    361440    #set parameters for each convolver
     
    426505                    NISTpk,ttArr,twoth_peak,simParms['calcwid'],
    427506                    simParms['step'])
    428             except:
     507            except Exception as err:
    429508                if msg: msg += '\n'
    430                 msg = "Error computing convolution, revise input"
     509                msg = "Error computing convolution, revise input. Error =\n"+str(err)
    431510                continue
    432511            if num == 0: G2plt.PlotFPAconvolutors(G2frame,NISTpk)
     
    467546        '''Perform a peak fit to the FP simulated pattern
    468547        '''
    469         plswait = wx.Dialog(G2frame,style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER)
    470         vbox = wx.BoxSizer(wx.VERTICAL)
    471         vbox.Add((1,1),1,wx.ALL|wx.EXPAND,1)
    472         txt = wx.StaticText(plswait,wx.ID_ANY,
    473                                 'Fitting peaks...\nPlease wait...',
    474                                 style=wx.ALIGN_CENTER)
    475         vbox.Add(txt,0,wx.ALL|wx.EXPAND)
    476         vbox.Add((1,1),1,wx.ALL|wx.EXPAND,1)
    477         plswait.SetSizer(vbox)
    478         plswait.Layout()
    479         plswait.CenterOnParent()
    480         plswait.Show() # post "please wait"
     548        pgbar = wx.ProgressDialog('FPA Simulation','Starting FPA simulation',100,
     549            parent=G2frame,
     550            style = wx.PD_ELAPSED_TIME|wx.PD_AUTO_HIDE #|wx.PD_CAN_ABORT
     551            )
     552        pgbar.Raise()
    481553        wx.BeginBusyCursor()
    482554        # pick out one or two most intense wavelengths
     
    515587        except:
    516588            pass
    517            
     589        GoOn = pgbar.Update(5,newmsg='Creating peak list')
     590        pgbar.Raise()
    518591        for pos in peaklist:
    519592            i = ttArr.searchsorted(pos)
    520593            area = sum(intArr[max(0,i-maxPtsHM):min(len(intArr),i+maxPtsHM)])
    521594            peakData['peaks'].append(G2mth.setPeakparms(Parms,Parms2,pos,area))
     595        GoOn = pgbar.Update(10,newmsg='Refining peak positions')
    522596        histData = G2frame.GPXtree.GetItemPyData(histId)
    523597        # refine peak positions only
     
    527601                                            Parms,Parms2,histData[1],bxye,[],
    528602                                           False,controldat,None)[0]
     603        GoOn = pgbar.Update(20,newmsg='Refining peak positions && areas')
    529604        # refine peak areas as well
    530605        for pk in peakData['peaks']:
     
    534609                                            Parms,Parms2,histData[1],bxye,[],
    535610                                           False,controldat)[0]
     611        GoOn = pgbar.Update(40,newmsg='Refining profile function')
    536612        # refine profile function
    537613        for p in ('U', 'V', 'W', 'X', 'Y'):
     
    541617                                            Parms,Parms2,histData[1],bxye,[],
    542618                                           False,controldat)[0]
     619        GoOn = pgbar.Update(70,newmsg='Refining profile function && asymmetry')
    543620        # add in asymmetry
    544621        Parms['SH/L'][2] = True
     
    547624                                            Parms,Parms2,histData[1],bxye,[],
    548625                                           False,controldat)[0]
     626        GoOn = pgbar.Update(100,newmsg='Done')
    549627        # reset "initial" profile
    550628        for p in Parms:
     
    552630                Parms[p][0] = Parms[p][1]
    553631                Parms[p][2] = False
     632        pgbar.Destroy()
    554633        wx.EndBusyCursor()
    555         plswait.Destroy() # remove "please wait"
    556634        # save Iparms
    557635        pth = G2G.GetExportPath(G2frame)
     
    583661        FPdlg = wx.Dialog(dlg,wx.ID_ANY,'FPA parameters',
    584662                style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
    585         MakeTopasFPASizer(G2frame,FPdlg,'BBpoint',SetButtonStatus)
     663        MakeTopasFPASizer(G2frame,FPdlg,SetButtonStatus)
    586664        FPdlg.CenterOnParent()
    587665        FPdlg.Raise()
     
    692770    return
    693771       
     772if __name__ == "__main__":
     773    app = wx.PySimpleApp()
     774    GSASIIpath.InvokeDebugOpts()
     775    frm = wx.Frame(None) # create a frame
     776    frm.Show(True)
     777    frm.TutorialImportDir = '/tmp'
     778
     779    GetFPAInput(frm)
     780   
     781    app.MainLoop()
  • trunk/GSASIIplot.py

    r4389 r4403  
    1039010390    ttmin = ttmax = 0
    1039110391    #GSASIIpath.IPyBreak()
    10392     for i,conv in enumerate(NISTpk.convolvers):
     10392    i = -1
     10393    for conv in NISTpk.convolvers:
    1039310394        if 'smoother' in conv: continue
     10395        if 'crystallite_size' in conv: continue
    1039410396        f = NISTpk.convolver_funcs[conv]()
    1039510397        if f is None: continue
     10398        i += 1
    1039610399        FFT = FP.best_irfft(f)
    1039710400        if f[1].real > 0: FFT = np.roll(FFT,int(len(FFT)/2.))
  • trunk/NIST_profile/__init__.py

    r3571 r4403  
    11from __future__ import absolute_import
    22from .profile_functions_class import FP_profile, best_irfft, best_rfft
     3from .atan_windowed_FP_profile import FP_atan_windowed_convolver
     4
     5class FP_windowed(FP_atan_windowed_convolver, FP_profile):
     6    pass
     7
     8
Note: See TracChangeset for help on using the changeset viewer.