Changeset 1282 for trunk/GSASIIgrid.py


Ignore:
Timestamp:
Apr 18, 2014 10:22:29 AM (8 years ago)
Author:
toby
Message:

sequential refinement updates

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/GSASIIgrid.py

    r1281 r1282  
    3131import GSASIImath as G2mth
    3232import GSASIIIO as G2IO
     33import GSASIIstrIO as G2stIO
    3334import GSASIIlattice as G2lat
    3435import GSASIIplot as G2plt
     
    132133] = [wx.NewId() for item in range(9)]
    133134
    134 [ wxID_SAVESEQSEL,
    135 ] = [wx.NewId() for item in range(1)]
     135[ wxID_SAVESEQSEL,wxID_SAVESEQSELCSV,wxID_PLOTSEQSEL,
     136] = [wx.NewId() for item in range(3)]
    136137
    137138[ wxID_MODELCOPY,wxID_MODELFIT,wxID_MODELADD,wxID_ELEMENTADD,wxID_ELEMENTDELETE,
     
    24492450        self.PrefillDataMenu(self.SequentialMenu,helpType='Sequential',helpLbl='Sequential Refinement')
    24502451        self.SequentialFile = wx.Menu(title='')
    2451         self.SequentialMenu.Append(menu=self.SequentialFile, title='File')
    2452         self.SequentialFile.Append(id=wxID_SAVESEQSEL, kind=wx.ITEM_NORMAL,text='Save...',
    2453             help='Save selected sequential refinement results')
     2452        self.SequentialMenu.Append(menu=self.SequentialFile, title='Selected Cols')
     2453        self.SequentialFile.Append(id=wxID_SAVESEQSEL, kind=wx.ITEM_NORMAL,text='Save as text',
     2454            help='Save selected sequential refinement results as a text file')
     2455        self.SequentialFile.Append(id=wxID_SAVESEQSELCSV, kind=wx.ITEM_NORMAL,text='Save as CSV',
     2456            help='Save selected sequential refinement results as a CSV spreadsheet file')
     2457        self.SequentialFile.Append(id=wxID_PLOTSEQSEL, kind=wx.ITEM_NORMAL,text='Plot selected',
     2458            help='Plot selected sequential refinement results')
    24542459        self.PostfillDataMenu()
    24552460           
     
    34923497            * 'histNames' - list of histogram names in order as processed by Sequential Refinement
    34933498            * 'varyList' - list of variables - identical over all refinements in sequence
    3494             * 'histName' - dictionaries for all data sets processed, which contains:
     3499              note that this is the original list of variables, prior to processing
     3500              constraints.
     3501            * keyed by histName - dictionaries for all data sets processed, which contains:
    34953502
    34963503              * 'variables'- result[0] from leastsq call
    3497               * 'varyList' - list of variables; same as above
     3504              * 'varyList' - list of variables passed to leastsq call (not same as above)
    34983505              * 'sig' - esds for variables
    34993506              * 'covMatrix' - covariance matrix from individual refinement
     
    35023509              * 'newCellDict' - new cell parameters after shifts to A0-A5 applied'
    35033510    """
    3504     if not data:
    3505         print 'No sequential refinement results'
    3506         return
    3507     histNames = data['histNames']
    3508        
     3511
    35093512    def GetSampleParms():
     3513        '''Make a dictionary of the sample parameters are not the same over the
     3514        refinement series.
     3515        '''
    35103516        sampleParmDict = {'Temperature':[],'Pressure':[],
    35113517                          'FreePrm1':[],'FreePrm2':[],'FreePrm3':[],}
     
    35213527                sampleParm[item] = sampleParmDict[item]           
    35223528        return sampleParm
     3529
     3530    def GetColumnVals(col):
     3531        'returns lists of values and errors (or None) for each column in the table'
     3532        return colList[col],colSigs[col]
    35233533           
    3524     def GetRwps():
    3525         Rwps = []
    3526         for name in histNames:
    3527             Rwps.append(data[name]['Rvals']['Rwp'])
    3528         return Rwps
    3529            
    3530     def GetSigData(parm):
    3531         sigData = []
    3532         for name in histNames:
    3533             sigList = data[name]['sig']
    3534             if colLabels[parm] in atomList:
    3535                 sigData.append(sigList[colLabels.index(atomList[colLabels[parm]])-1])
    3536             elif colLabels[parm] in cellList:
    3537                 sigData.append(sigList[colLabels.index(cellList[colLabels[parm]])-1])
    3538             else:
    3539                 sigData.append(sigList[parm-1])
    3540         return sigData
    3541    
    3542     def Select(event):
     3534    def PlotSelect(event):
     3535        'Plots a row (covariance) or column on double-click'
    35433536        cols = G2frame.dataDisplay.GetSelectedCols()
    35443537        rows = G2frame.dataDisplay.GetSelectedRows()
    35453538        if cols:
    3546             plotData = []
    3547             plotSig = []
    3548             plotNames = []
    35493539            for col in cols:
    3550                 plotData.append(G2frame.SeqTable.GetColValues(col))
    3551                 if col:     #not Rwp
    3552                     plotSig.append(GetSigData(col))
    3553                 else:
    3554                     plotSig.append(0.0)
    3555                 plotNames.append(G2frame.SeqTable.GetColLabelValue(col))
    3556             plotData = np.array(plotData)
    3557             G2plt.PlotSeq(G2frame,plotData,plotSig,plotNames,sampleParms)
     3540                plotName = plotSpCharFix(G2frame.SeqTable.GetColLabelValue(col))
     3541                data,sigs = GetColumnVals(col)
     3542                G2plt.PlotSeq(G2frame,[data],[sigs],[plotName])
     3543                break # stop after 1st
    35583544        elif rows:
    35593545            name = histNames[rows[0]]       #only does 1st one selected
    35603546            G2plt.PlotCovariance(G2frame,data[name])
     3547
     3548    def OnPlotSelSeq(event):
     3549        'plot the selected columns from menu command'
     3550        cols = sorted(G2frame.dataDisplay.GetSelectedCols()) # ignore selection order
     3551        print cols
     3552        nrows = G2frame.SeqTable.GetNumberRows()
     3553        if not cols:
     3554            G2frame.ErrorDialog(
     3555                'Select columns',
     3556                'No columns selected in table. Click on column labels to select fields for output.'
     3557                )
     3558            return
     3559        #saveNames = [G2frame.SeqTable.GetRowLabelValue(r) for r in range(nrows)]
     3560        saveData = []
     3561        saveSigs = []
     3562        plotNames = [plotSpCharFix(G2frame.SeqTable.GetColLabelValue(col)) for col in cols]
     3563        for col in cols:
     3564            vals,sigs = GetColumnVals(col)
     3565            saveData.append(vals)
     3566            saveSigs.append(sigs)
     3567        G2plt.PlotSeq(G2frame,saveData,saveSigs,plotNames)
    35613568           
    3562     def OnSaveSelSeq(event):       
    3563         cols = G2frame.dataDisplay.GetSelectedCols()
    3564         if cols:
    3565             numRows = G2frame.SeqTable.GetNumberRows()
    3566             dataNames = []
    3567             saveNames = [G2frame.SeqTable.GetRowLabelValue(r) for r in range(numRows)]
    3568             saveData = []
     3569    def OnSaveSelSeqCSV(event):
     3570        'export the selected columns to a .csv file from menu command'
     3571        OnSaveSelSeq(event,csv=True)
     3572       
     3573    def OnSaveSelSeq(event,csv=False):
     3574        'export the selected columns to a .txt file from menu command'
     3575        def WriteCSV():
     3576            def WriteList(headerItems):
     3577                line = ''
     3578                for lbl in headerItems:
     3579                    if line: line += ','
     3580                    line += '"'+lbl+'"'
     3581                return line
     3582            head = ['name']
    35693583            for col in cols:
    3570                 dataNames.append(G2frame.SeqTable.GetColLabelValue(col))
    3571                 if col:     #not Rwp
    3572                     saveData.append(zip(G2frame.SeqTable.GetColValues(col),GetSigData(col)))
     3584                item = G2frame.SeqTable.GetColLabelValue(col)
     3585                if col in havesig:
     3586                    head += [item,'esd-'+item]
    35733587                else:
    3574                     saveData.append(zip(G2frame.SeqTable.GetColValues(col),0.0))
     3588                    head += [item]
     3589            SeqFile.write(WriteList(head)+'\n')
     3590            for row,name in enumerate(saveNames):
     3591                line = '"'+saveNames[row]+'"'
     3592                for col in cols:
     3593                    if col in havesig:
     3594                        line += ','+str(saveData[col][row])+','+str(saveSigs[col][row])
     3595                    else:
     3596                        line += ','+str(saveData[col][row])
     3597                SeqFile.write(line+'\n')
     3598        def WriteSeq():
    35753599            lenName = len(saveNames[0])
    3576             saveData = np.swapaxes(np.array(saveData),0,1)
    3577             dlg = wx.FileDialog(G2frame, 'Choose text output file for your selection', '.', '',
    3578                 'Text output file (*.txt)|*.txt',wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
    3579             try:
    3580                 if dlg.ShowModal() == wx.ID_OK:
    3581                     SeqTextFile = dlg.GetPath()
    3582                     SeqTextFile = G2IO.FileDlgFixExt(dlg,SeqTextFile)
    3583                     SeqFile = open(SeqTextFile,'w')
    3584                     line = '  %s  '%('name'.center(lenName))
    3585                     for item in dataNames:
    3586                         line += ' %12s %12s '%(item.center(12),'esd'.center(12))
    3587                     line += '\n'
    3588                     SeqFile.write(line)
    3589                     for i,item in enumerate(saveData):
    3590                         line = " '%s' "%(saveNames[i])
    3591                         for val,esd in item:
    3592                             line += ' %12.6f %12.6f '%(val,esd)
    3593                         line += '\n'
    3594                         SeqFile.write(line)
    3595                     SeqFile.close()
    3596             finally:
    3597                 dlg.Destroy()
    3598            
    3599                
     3600            line = '  %s  '%('name'.center(lenName))
     3601            for col in cols:
     3602                item = G2frame.SeqTable.GetColLabelValue(col)
     3603                if col in havesig:
     3604                    line += ' %12s %12s '%(item.center(12),'esd'.center(12))
     3605                else:
     3606                    line += ' %12s '%(item.center(12))
     3607            SeqFile.write(line+'\n')
     3608            for row,name in enumerate(saveNames):
     3609                line = " '%s' "%(saveNames[row])
     3610                for col in cols:
     3611                    if col in havesig:
     3612                        line += ' %12.6f %12.6f '%(saveData[col][row],saveSigs[col][row])
     3613                    else:
     3614                        line += ' %12.6f '%saveData[col][row]
     3615                SeqFile.write(line+'\n')
     3616
     3617        cols = sorted(G2frame.dataDisplay.GetSelectedCols()) # ignore selection order
     3618        nrows = G2frame.SeqTable.GetNumberRows()
     3619        if not cols:
     3620            G2frame.ErrorDialog('Select columns',
     3621                             'No columns selected in table. Click on column labels to select fields for output.')
     3622            return
     3623        saveNames = [G2frame.SeqTable.GetRowLabelValue(r) for r in range(nrows)]
     3624        saveData = {}
     3625        saveSigs = {}
     3626        havesig = []
     3627        for col in cols:
     3628            vals,sigs = GetColumnVals(col)
     3629            saveData[col] = vals
     3630            if sigs:
     3631                havesig.append(col)
     3632                saveSigs[col] = sigs
     3633        if csv:
     3634            wild = 'CSV output file (*.csv)|*.csv'
     3635        else:
     3636            wild = 'Text output file (*.txt)|*.txt'
     3637        dlg = wx.FileDialog(
     3638            G2frame,
     3639            'Choose text output file for your selection', '.', '',
     3640            wild,wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR)
     3641        try:
     3642            if dlg.ShowModal() == wx.ID_OK:
     3643                SeqTextFile = dlg.GetPath()
     3644                SeqTextFile = G2IO.FileDlgFixExt(dlg,SeqTextFile)
     3645                SeqFile = open(SeqTextFile,'w')
     3646                if csv:
     3647                    WriteCSV()
     3648                else:
     3649                    WriteSeq()
     3650                SeqFile.close()
     3651        finally:
     3652            dlg.Destroy()
     3653    # lookup table for unique cell parameters by symmetry
     3654    cellGUIlist = [
     3655        [['m3','m3m'],(0,)],
     3656        [['3R','3mR'],(0,3)],
     3657        [['3','3m1','31m','6/m','6/mmm','4/m','4/mmm'],(0,2)],
     3658        [['mmm'],(0,1,2)],
     3659        [['2/m'+'a'],(0,1,2,3)],
     3660        [['2/m'+'b'],(0,1,2,4)],
     3661        [['2/m'+'c'],(0,1,2,5)],
     3662        [['-1'],(0,1,2,3,4,5)],
     3663        ]
     3664    def striphist(var):
     3665        'strip a histogram number from a var name'
     3666        sv = var.split(':')
     3667        sv[1] = ''
     3668        return ':'.join(sv)
     3669    def plotSpCharFix(lbl):
     3670        'Change selected unicode characters to their matplotlib equivalent'
     3671        for u,p in [
     3672            (u'\u03B1',r'$\alpha$'),
     3673            (u'\u03B2',r'$\beta$'),
     3674            (u'\u03b3',r'$\gamma$'),
     3675            (u'\u0394\u03C7',r'$\Delta\chi$'),
     3676            ]:
     3677            lbl = lbl.replace(u,p)
     3678        return lbl
     3679
     3680    #======================================================================
     3681    # start processing sequential results here
     3682    if not data:
     3683        print 'No sequential refinement results'
     3684        return
     3685    histNames = data['histNames']
    36003686    if G2frame.dataDisplay:
    36013687        G2frame.dataDisplay.Destroy()
    3602     atomList = {}
    3603     newAtomDict = data[histNames[0]]['newAtomDict']
    3604     for item in newAtomDict:
    3605         if item in data['varyList']:
    3606             atomList[newAtomDict[item][0]] = item
    3607     cellList = {}
     3688    if not G2frame.dataFrame.GetStatusBar():
     3689        Status = G2frame.dataFrame.CreateStatusBar()
     3690        Status.SetStatusText("Select column to export; Double click on column to plot data; on row for Covariance")
     3691    # make dict of varied atom coords keyed by absolute position
     3692    newAtomDict = data[histNames[0]]['newAtomDict'] # dict with atom positions; relative & absolute
     3693    # Possible error: the next might need to be data[histNames[0]]['varyList']
     3694    # error will arise if there constraints on coordinates?
     3695    atomList = {newAtomDict[item][0]:item for item in newAtomDict if item in data['varyList']}
     3696   
     3697    # make dict of varied cell parameters equivalents
     3698    ESDlookup = {} # provides the Dij term for each Ak term (where terms are refined)
     3699    Dlookup = {} # provides the Ak term for each Dij term (where terms are refined)
     3700    # N.B. These Dij vars are missing a histogram #
    36083701    newCellDict = data[histNames[0]]['newCellDict']
    36093702    for item in newCellDict:
    36103703        if item in data['varyList']:
    3611             cellList[newCellDict[item][0]] = item
     3704            ESDlookup[newCellDict[item][0]] = item
     3705            Dlookup[item] = newCellDict[item][0]
     3706
     3707    # get unit cell & symmetry for all phases
     3708    cellUlbl = ('a','b','c',u'\u03B1',u'\u03B2',u'\u03b3') # unicode a,b,c,alpha,beta,gamma
     3709    #cellUlbl = ('a','b','c',r'$\alpha$',r'$\beta$',r'$\gamma$') # matplotlib a,b,c,alpha,beta,gamma
     3710    Phases = G2frame.GetPhaseData()
     3711    Alist = {}
     3712    SGdata = {}
     3713    covData = {}
     3714    uniqCellParms = {}
     3715    for phase in Phases:
     3716        phasedict = Phases[phase]
     3717        pId = phasedict['pId']
     3718        Alist[pId] = G2lat.cell2A(phasedict['General']['Cell'][1:7])
     3719        SGdata[pId] = phasedict['General']['SGData']
     3720        laue = SGdata[pId]['SGLaue']
     3721        if laue == '2/m':
     3722            laue += SGdata[pId]['SGUniq']
     3723        for symlist,celllist in cellGUIlist:
     3724            if laue in symlist:
     3725                uniqCellParms[pId] = celllist
     3726                break
     3727        else: # should not happen
     3728            uniqCellParms[pId] = range(6)
     3729
    36123730    sampleParms = GetSampleParms()
    3613     Rwps = GetRwps()
    36143731    SetDataMenuBar(G2frame,G2frame.dataFrame.SequentialMenu)
    36153732    G2frame.dataFrame.SetLabel('Sequential refinement results')
    36163733    G2frame.dataFrame.CreateStatusBar()
    36173734    G2frame.dataFrame.Bind(wx.EVT_MENU, OnSaveSelSeq, id=wxID_SAVESEQSEL)
    3618     colLabels = ['Rwp',]+data['varyList']+atomList.keys()+cellList.keys()
    3619     Types = (len(data['varyList']+atomList.keys()+cellList.keys())+1)*[wg.GRID_VALUE_FLOAT,]
    3620     seqList = [[Rwps[i],]+list(data[name]['variables']) for i,name in enumerate(histNames)]
    3621     for i,item in enumerate(seqList):
    3622         newAtomDict = data[histNames[i]]['newAtomDict']
    3623         newCellDict = data[histNames[i]]['newCellDict']
    3624         item += [newAtomDict[atomList[parm]][1] for parm in atomList.keys()]
    3625         item += [newCellDict[cellList[parm]][1] for parm in cellList.keys()]
    3626     G2frame.SeqTable = Table(seqList,colLabels=colLabels,rowLabels=histNames,types=Types)
     3735    G2frame.dataFrame.Bind(wx.EVT_MENU, OnSaveSelSeqCSV, id=wxID_SAVESEQSELCSV)
     3736    G2frame.dataFrame.Bind(wx.EVT_MENU, OnPlotSelSeq, id=wxID_PLOTSEQSEL)
     3737    # build up the table one column at a time
     3738    colList = []
     3739    colSigs = []
     3740    colLabels = []
     3741    Types = []
     3742    nRows = len(histNames)
     3743    # add Rwp values
     3744    colList += [[data[name]['Rvals']['Rwp'] for name in histNames]]
     3745    colSigs += [None]
     3746    colLabels += ['Rwp']
     3747    Types += [wg.GRID_VALUE_FLOAT,]
     3748    # add Converged flag
     3749    colList += [[100.*data[name]['Rvals'].get('DelChi2',-1) for name in histNames]]
     3750    colSigs += [None]
     3751    colLabels += [u'\u0394\u03C7\u00B2 (%)']
     3752    Types += [wg.GRID_VALUE_FLOAT,]
     3753
     3754    # colList += [[data[name]['Rvals']['converged'] for name in histNames]]
     3755    # colSigs += [None]
     3756    # colLabels += ['Cnvg']
     3757    # Types += [wg.GRID_VALUE_BOOL,]
     3758    # add sample parameters
     3759    for key in sampleParms:
     3760        colList += [sampleParms[key]]
     3761        colSigs += [None]
     3762        colLabels += [key]
     3763        Types += [wg.GRID_VALUE_FLOAT,]
     3764
     3765    # add cell parameters
     3766    for pId in sorted(Alist):
     3767        pfx = str(pId)+'::' # prefix for A values from phase
     3768        cells = []
     3769        cellESDs = []
     3770        colLabels += [pfx+cellUlbl[i] for i in uniqCellParms[pId]]
     3771        Types += len(uniqCellParms[pId])*[wg.GRID_VALUE_FLOAT,]
     3772        for name in histNames:
     3773            covData['varyList'] = [Dlookup.get(striphist(v),v) for v in data[name]['varyList']]
     3774            covData['covMatrix'] = data[name]['covMatrix']
     3775            A = Alist[pId][:] # make copy of starting A values
     3776            # update with refined values
     3777            for i in range(6):
     3778                var = str(pId)+'::A'+str(i)
     3779                if var in ESDlookup:
     3780                    val = data[name]['newCellDict'][ESDlookup[var]][1] # get refined value
     3781                    A[i] = val # override with updated value
     3782            # apply symmetry
     3783            Albls = [pfx+'A'+str(i) for i in range(6)]
     3784            cellDict = dict(zip(Albls,A))
     3785            zeroDict = dict(zip(Albls,6*[0.,]))
     3786            A,zeros = G2stIO.cellFill(pfx,SGdata[pId],cellDict,zeroDict)
     3787            # convert to direct cell & add only unique values to table
     3788            c = G2lat.A2cell(A)
     3789            cE = G2stIO.getCellEsd(pfx,SGdata[pId],A,covData)
     3790            cells += [[c[i] for i in uniqCellParms[pId]]]
     3791            cellESDs += [[cE[i] for i in uniqCellParms[pId]]]
     3792        colList += zip(*cells)
     3793        colSigs += zip(*cellESDs)
     3794
     3795    # add the variables that were refined; change from rows to columns
     3796    colList += zip(*[data[name]['variables'] for name in histNames])
     3797    colLabels += data[histNames[0]]['varyList']
     3798    Types += len(data[histNames[0]]['varyList'])*[wg.GRID_VALUE_FLOAT]
     3799    colSigs += zip(*[data[name]['sig'] for name in histNames])
     3800   
     3801    # process the dependent constrained variables, removing histogram numbers if needed
     3802    depValDict = {}
     3803    depSigDict = {}
     3804    for name in histNames:
     3805        for var in data[name].get('depParmDict',{}):
     3806            val,sig = data[name]['depParmDict'][var]
     3807            sv = var.split(':')
     3808            if sv[1] != '': sv[1] = '*'
     3809            svar = ':'.join(sv)
     3810            if svar not in depValDict:
     3811               depValDict[svar] = [val]
     3812               depSigDict[svar] = [sig]
     3813            else:
     3814               depValDict[svar].append(val)
     3815               depSigDict[svar].append(sig)
     3816    # add the dependent constrained variables
     3817    for var in sorted(depValDict):
     3818        if len(depValDict[var]) != len(histNames): continue
     3819        colLabels.append(var)
     3820        Types += [wg.GRID_VALUE_FLOAT,]
     3821        colSigs += [depSigDict[var]]
     3822        colList += [depValDict[var]]
     3823
     3824    # add atom parameters to list
     3825    colLabels += atomList.keys()
     3826    Types += len(atomList)*[wg.GRID_VALUE_FLOAT]
     3827    for parm in atomList:
     3828        colList += [[data[name]['newAtomDict'][atomList[parm]][1] for name in histNames]]
     3829
     3830    rowList = [c for c in zip(*colList)]     # convert from columns to rows
     3831    G2frame.SeqTable = Table(rowList,colLabels=colLabels,rowLabels=histNames,types=Types)
     3832
     3833    # Rwps = [data[name]['Rvals']['Rwp'] for name in histNames]
     3834    # seqList = [[Rwps[i],]+list(data[name]['variables']) for i,name in enumerate(histNames)]
     3835    # for i,item in enumerate(seqList):
     3836    #      newAtomDict = data[histNames[i]]['newAtomDict']
     3837    #      newCellDict = data[histNames[i]]['newCellDict']
     3838    #      item += [newAtomDict[atomList[parm]][1] for parm in atomList.keys()]
     3839    #      item += [newCellDict[ESDlookup[parm]][1] for parm in ESDlookup.keys()]
     3840    # colLabels = ['Rwp',]+data['varyList']  +atomList.keys()+ESDlookup.keys()
     3841    # Types = (len(data['varyList'] +atomList.keys()+ESDlookup.keys()
     3842    #              )+1)*[wg.GRID_VALUE_FLOAT,]
     3843    # G2frame.SeqTable = Table(seqList,colLabels=colLabels,rowLabels=histNames,types=Types
     3844    #                         )
    36273845    G2frame.dataDisplay = GSGrid(parent=G2frame.dataFrame)
    36283846    G2frame.dataDisplay.SetTable(G2frame.SeqTable, True)
    36293847    G2frame.dataDisplay.EnableEditing(False)
    3630     G2frame.dataDisplay.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, Select)
     3848    G2frame.dataDisplay.Bind(wg.EVT_GRID_LABEL_LEFT_DCLICK, PlotSelect)
    36313849    G2frame.dataDisplay.SetRowLabelSize(8*len(histNames[0]))       #pretty arbitrary 8
    36323850    G2frame.dataDisplay.SetMargins(0,0)
    36333851    G2frame.dataDisplay.AutoSizeColumns(True)
    36343852    G2frame.dataFrame.setSizePosLeft([700,350])
    3635        
    36363853################################################################################
    36373854#####  Main PWDR panel
Note: See TracChangeset for help on using the changeset viewer.