Changeset 3592


Ignore:
Timestamp:
Sep 11, 2018 5:10:24 PM (3 years ago)
Author:
toby
Message:

add Igor Pro export to publication plot -- thanks to Jan Ilavsky

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/GSASIIplot.py

    r3588 r3592  
    29562956        plotOpt['fmtChoices'].append('Data file with plot elements, csv')
    29572957        plotOpt['fmtChoices'].append('Grace input file, agr')
     2958        plotOpt['fmtChoices'].append('Igor Pro input file, itx')
    29582959        if plotOpt['format'] is None:
    29592960            if 'pdf' in fmtDict:
     
    31253126            if 'mag' not in lbl: continue
    31263127            #ax0.axvline(l.get_data()[0][0],color='0.5',dashes=(1,1))
    3127             # verical line
     3128            # vertical line
    31283129            s = '@with line\n@ line on\n@ line loctype world\n@ line g0\n'
    31293130            fp.write(s)
     
    32753276        fp.close()
    32763277        print('file',filename,'written')
    3277        
     3278
     3279    def CopyRietveld2Igor(Pattern,Plot,Page,plotOpt,filename,G2frame):
     3280        '''Copy the contents of the Rietveld graph from the plot window to
     3281        a Igor Pro input file (tested with v7.05). Uses values from Pattern
     3282        to also generate a delta/sigma plot below.
     3283
     3284        Coded with lots of help from Jan Ilavsky.
     3285        '''
     3286        import itertools # delay this until called, since not commonly needed
     3287        InameDict = {'obs':'Intensity', 'calc':'FitIntensity',
     3288                        'bkg':'Background','diff':'Difference',
     3289                        'omcos':'NormResidual','zero':'Zero'}
     3290        igor_symbols = {"o":19, "s":18, "D":29, "^":17, "3":46, 'v':23,
     3291                "4":49, "+":1, "P":60, "x":0, "X":62, "*":2}
     3292        def Write2cols(fil,dataItems):
     3293                '''Write a line to a file in space-separated columns.
     3294                Skips masked items.
     3295
     3296                :param object fil: file object
     3297                :param list dataItems: items to write as row in file
     3298                '''
     3299                line = ''
     3300                for item in dataItems:
     3301                    if ma.is_masked(item): return
     3302                    if line: line += ' '
     3303                    item = str(item)
     3304                    if ' ' in item:
     3305                        line += '"'+item+'"'
     3306                    else:
     3307                        line += item
     3308                fil.write(line+'\n')
     3309        proj = os.path.splitext(G2frame.GSASprojectfile)[0]
     3310        if not proj: proj = 'GSASIIproject'
     3311        proj = proj.replace(' ','')
     3312        valueList = []
     3313        markerSettings = []
     3314        Icolor = {}
     3315        legends = []
     3316        zerovals = None
     3317        fontsize = 18*float(plotOpt['labelSize'])/12.
     3318        for i,l in enumerate(Plot.lines):
     3319            lbl = l.get_label()
     3320            if plotOpt['legend'].get(lbl[1:]):
     3321                legends.append((InameDict[lbl[1:]],lbl[1:]))
     3322            if 'mag' in lbl:
     3323                pass
     3324            elif lbl[1:] in ('obs','calc','bkg','zero','diff'):
     3325                if lbl[1:] == 'obs':
     3326                    x = l.get_xdata()
     3327                    valueList.append(x)
     3328                    zerovals = (x.min(),x.max())
     3329                    gsiz = 5*float(plotOpt['markerSiz'])/8.
     3330                    marker = plotOpt['markerSym']
     3331                    gsym = igor_symbols.get(marker,12)
     3332                    gmw = float(plotOpt['markerWid'])
     3333                    markerSettings.append(
     3334                        'mode({0})=3,marker({0})={1},msize({0})={2},mrkThick({0})={3}'
     3335                        .format('Intensity',gsym,gsiz,gmw))
     3336                else:
     3337                    markerSettings.append(
     3338                        'mode({0})=0, lsize({0})={1}'
     3339                        .format(InameDict[lbl[1:]],plotOpt['lineWid']))
     3340                c = plotOpt['colors'].get(lbl[1:],l.get_color())
     3341                #if sum(c) == 4.0: continue
     3342                Icolor[InameDict[lbl[1:]]] = [j*65535 for j in c[0:3]]
     3343                if lbl[1:] != 'zero':
     3344                    valueList.append(l.get_ydata())
     3345        valueList.append(Pattern[1][5]*np.sqrt(Pattern[1][2]))
     3346        # invert lists into columns, use iterator for all values
     3347        if hasattr(itertools,'zip_longest'): #Python 3+
     3348            invertIter = itertools.zip_longest(*valueList,fillvalue=' ')
     3349        else:
     3350            invertIter = itertools.izip_longest(*valueList,fillvalue=' ')
     3351        fp = open(filename,'w')
     3352        fp.write('''IGOR
     3353X setDataFolder root:
     3354X //   ***   Replace GSAS2Data with name of current project in GSAS.
     3355X //   ***   this name will get "order" number (0,1,2...) to be unique and data will be stored there.
     3356X //   ***   and the graph will also be named using this base name.
     3357X NewDataFolder/O/S $(UniqueName(CleanupName("{}",0),11, 0))
     3358X string GSAXSProjectName = GetDataFolder(0)
     3359WAVES /D/O TwoTheta, Intensity, FitIntensity, Background, Difference, NormResidual
     3360BEGIN
     3361'''.format(proj))
     3362        for row in invertIter:
     3363            Write2cols(fp,row)
     3364        fp.write('''END
     3365X //  ***   static part of the code, NB reflection tickmarks later ****
     3366X SetScale d 0,0, "degree", TwoTheta
     3367X //  ***   this is where graph is created and data added
     3368X string G_Name=CleanupName(GSAXSProjectName,0)
     3369X Display/K=1/W=(50,40,850,640) Intensity vs twoTheta; DoWindow/C $(G_Name)
     3370X DoWindow/T $(G_Name), G_Name
     3371X AppendToGraph FitIntensity vs TwoTheta
     3372X AppendToGraph Background vs TwoTheta
     3373X AppendToGraph Difference vs TwoTheta
     3374X AppendToGraph/L=Res_left/B=Res_bot NormResidual vs TwoTheta
     3375X //  ***   Here we have modification of the four axes used in the graph
     3376X ModifyGraph mode=2,lsize=5, mirror=2
     3377X SetAxis/A/E=2 Res_left
     3378X ModifyGraph freePos(Res_left)={0,kwFraction}
     3379X ModifyGraph freePos(Res_bot)={0.2,kwFraction}
     3380X ModifyGraph standoff(bottom)=0
     3381X ModifyGraph axisEnab(left)={0.2,1}
     3382X ModifyGraph axisEnab(Res_left)={0,0.2}
     3383X ModifyGraph lblPosMode(Res_left)=1, mirror(Res_bot)=0
     3384X ModifyGraph tickUnit(bottom)=1,manTick=0,manMinor(bottom)={0,50}
     3385X ModifyGraph tick(Res_bot)=1,noLabel(Res_bot)=2,standoff(Res_bot)=0
     3386X ModifyGraph manMinor(Res_bot)={0,50},tick(Res_bot)=2
     3387X ModifyGraph axThick=2
     3388X ModifyGraph mirror(Res_bot)=0,nticks(Res_left)=3,highTrip(left)=1e+06,manTick(bottom)=0
     3389X ModifyGraph btLen=5
     3390''')
     3391        fp.write('X ModifyGraph gfSize={}\n'.format(int(fontsize+.5)))
     3392       
     3393        # line at zero
     3394        if not zerovals:
     3395            zerovals = (Plot.get_xlim()[0],Plot.get_xlim()[1])
     3396        fp.write('X //  ***   add line at y=zero\n')
     3397        fp.write('WAVES /D/O ZeroX, Zero\nBEGIN\n')
     3398        fp.write(' {0} 0.0\n {1} 0.0\n'.format(*zerovals))
     3399        fp.write('END\nX AppendToGraph Zero vs ZeroX\n')
     3400        fp.write('''X //  ***   add axis labels and position them
     3401X Label left "{1}"
     3402X Label Res_left "{2}"
     3403X Label bottom "{0}"
     3404X ModifyGraph lblPosMode=0,lblPos(Res_left)=84
     3405'''.format("2Θ","Intensity","∆/σ"))
     3406        fp.write('''X //  ***   set display limits.
     3407X SetAxis left {2}, {3}
     3408X SetAxis bottom {0}, {1}
     3409X SetAxis Res_bot {0}, {1}
     3410'''
     3411                    .format(Plot.get_xlim()[0],Plot.get_xlim()[1],
     3412                                    Plot.get_ylim()[0],Plot.get_ylim()[1]))
     3413        fp.write('X //  ***   modify how data are displayed ****\n')
     3414#         fp.write(
     3415# '''X //  ***   here starts mostly static part of the code, here we modify how data are displayed ****
     3416# X ModifyGraph mode(FitIntensity)=0,rgb(FitIntensity)=(1,39321,19939), lsize(FitIntensity)=1
     3417# X ModifyGraph mode(Background)=0,lsize(Background)=2, rgb(Background)=(65535,0,0)
     3418# X ModifyGraph mode(Difference)=0,lsize(Difference)=2,rgb(Difference)=(0,65535,65535)
     3419# X //  ***   modifications for the bottom graph, here we modify how data are displayed ****
     3420# X ModifyGraph mode(NormResidual)=0,lsize(NormResidual)=1,rgb(NormResidual)=(0,0,0)
     3421# X //  ***   end of modifications for the main data in graph
     3422# ''')
     3423        for m in markerSettings:
     3424                fp.write('X ModifyGraph {}\n'.format(m))
     3425        for lbl in Icolor:
     3426                fp.write('X ModifyGraph rgb({})=({:.0f},{:.0f},{:.0f})\n'
     3427                                 .format(lbl,*Icolor[lbl]))
     3428        fp.write('X ModifyGraph mode(NormResidual)=0,lsize(NormResidual)=1,rgb(NormResidual)=(0,0,0)\n')
     3429        fp.write('X //  ***   End modify how data are displayed ****\n')
     3430        # loop over reflections
     3431        ticknum = 0
     3432        for i,l in enumerate(Plot.lines):
     3433            lbl = l.get_label()
     3434            if l in Page.tickDict.values():
     3435                c = plotOpt['colors'].get(lbl,l.get_color())
     3436                if sum(c) == 4.0: continue # white is invisible
     3437                ticknum += 1
     3438                phasename = 'tick{}'.format(ticknum)
     3439                if plotOpt['legend'].get(lbl):
     3440                    legends.append((phasename,plotOpt['phaseLabels'].get(lbl,lbl)))
     3441                tickpos = l.get_ydata()[0]
     3442                fp.write(
     3443'''X //  reflection tickmark for phase {1}
     3444WAVES /D/O {0}X, {0}
     3445BEGIN
     3446'''.format(phasename,lbl))
     3447                for x in l.get_xdata():
     3448                    fp.write('{} {}\n'.format(x,tickpos))
     3449                fp.write('''END
     3450X //  ***   controls for {1} reflection tickmarks
     3451X AppendToGraph {0} vs {0}X
     3452X ModifyGraph mode({0})=3,mrkThick({0})=2,gaps({0})=0
     3453X ModifyGraph marker({0})=10,rgb({0})=({2},{3},{4})
     3454'''.format(phasename,lbl,*[j*65535 for j in c[0:3]]))
     3455               
     3456        # plot magnification lines and labels
     3457        j = 0
     3458        for i,l in enumerate(Plot.lines):
     3459            lbl = l.get_label()
     3460            if 'mag' not in lbl: continue
     3461            j += 1
     3462            fp.write('WAVES /D/O mag{0}X, mag{0}\nBEGIN\n'.format(j))
     3463            fp.write(' {0} {1}\n {0} {2}\n'.format(
     3464                l.get_data()[0][0],Plot.get_ylim()[0],Plot.get_ylim()[1]))
     3465            fp.write('END\nX AppendToGraph mag{0} vs mag{0}X\n'.format(j))
     3466            fp.write('X ModifyGraph lstyle(mag{0})=3,rgb(mag{0})=(0,0,0)\n'.format(j))
     3467        for l in Plot.texts:
     3468            if 'mag' not in l.get_label(): continue
     3469            if l.xycoords[0] == 'data':
     3470                xpos = l.get_position()[0]
     3471            elif l.get_position()[0] == 0:
     3472                xpos = Plot.get_xlim()[0]
     3473            else:
     3474                xpos = Plot.get_xlim()[1]*.95
     3475            fp.write('X SetDrawEnv xcoord=bottom, ycoord= abs,textyjust=2,fsize={}\n'.format(fontsize))
     3476            fp.write('X DrawText {0},2,"{1}"\n'.format(xpos,l.get_text()))
     3477
     3478        # legend
     3479        s = ""
     3480        for nam,txt in legends:
     3481            if s: s += r'\r'
     3482            s += r'\\s({}) {}'.format(nam,txt)
     3483        fp.write('X Legend/C/N=text0/J "{}"\n'.format(s))
     3484        fp.close()
     3485               
    32783486    def CopyRietveld2csv(Pattern,Plot,Page,filename):
    32793487        '''Copy the contents of the Rietveld graph from the plot window to
     
    33543562        elif 'agr' in typ and fil:
    33553563            CopyRietveld2Grace(Pattern,Plot,Page,plotOpt,fil)
     3564            dlg.EndModal(wx.ID_OK)
     3565        elif 'itx' in typ and fil:
     3566            CopyRietveld2Igor(Pattern,Plot,Page,plotOpt,fil,G2frame)
    33563567            dlg.EndModal(wx.ID_OK)
    33573568        elif fil:
     
    34293640   
    34303641    Note that the dpi value is ignored for svg and pdf files, which are
    3431     drawn with vector graphics (infinite resolution).
     3642    drawn with vector graphics (infinite resolution). Likewise, the agr and
     3643    itx options create input files for programs Grace (QtGrace) and Igor
     3644    Pro, that largely duplicate the displayed plot. Once read into Grace
     3645    or Igor the graphs can then be customized.
    34323646    '''
    34333647    hlp = G2G.HelpButton(dlg,helpinfo)
     
    35693783            else:
    35703784                uselbl = lbl
    3571             art = ax0.plot(l.get_xdata(),l.get_ydata(),color=c,
     3785            if lbl[1:] == 'zero':
     3786                art = ax0.axhline(0.,color=c,
     3787                     lw=lineWid,label=uselbl,ls=l.get_ls(),
     3788                     marker=marker,ms=siz,mew=mew)
     3789            else:
     3790                art = ax0.plot(l.get_xdata(),l.get_ydata(),color=c,
    35723791                     lw=lineWid,label=uselbl,ls=l.get_ls(),
    35733792                     marker=marker,ms=siz,mew=mew,
Note: See TracChangeset for help on using the changeset viewer.