Changeset 3820


Ignore:
Timestamp:
Feb 13, 2019 3:48:23 PM (3 years ago)
Author:
toby
Message:

implement integration in scripting

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/GSASIIscriptable.py

    r3815 r3820  
    1515=======================================
    1616
    17 Routines for reading, writing, modifying and creating GSAS-II project (.gpx) files.
    18 This file specifies several wrapper classes around GSAS-II data representations.
    19 They all inherit from :class:`G2ObjectWrapper`. The chief class is :class:`G2Project`,
    20 which represents an entire GSAS-II project and provides several methods to access
    21 phases, powder histograms, and execute Rietveld refinements. These routines can be
    22 accessed in two ways:
    23 the :ref:`CommandlineInterface` provides access a number of features without writing
    24 Python scripts of from the :ref:`API`, which allows much more versatile access from
    25 within Python.
    26 
    27 
    28 =====================
    29 Overview
    30 =====================
    31 The most commonly used routines are:
    32 
    33 :class:`G2Project`
    34    Always needed: used to create a new project (.gpx) file or read in an existing one.
    35 
    36 :meth:`G2Project.add_powder_histogram`
    37    Used to read in powder diffraction data to a project file.
    38 
    39 :meth:`G2Project.add_simulated_powder_histogram`
    40    Defines a "dummy" powder diffraction data that will be simulated after a refinement step.
    41 
    42 :meth:`G2Project.save`
    43    Writes the current project to disk.
    44 
    45 :meth:`G2Project.do_refinements`
    46    This is passed a list of dictionaries, where each dict defines a refinement step.
    47    Passing a list with a single empty dict initiates a refinement with the current
    48    parameters and flags.
    49    
    50 :meth:`G2Project.set_refinement`
    51    This is passed a single dict which is used to set parameters and flags.
    52    These actions can be performed also in :meth:`G2Project.do_refinements`.
    53 
    54 Refinement dicts
    55    A refinement dict sets up a single refinement step
    56    (as used in :meth:`G2Project.do_refinements` and described in
    57    :ref:`Project_dicts`).
    58    It specifies parameter & refinement flag changes, which are usually followed by a refinement and
    59    optionally by calls to locally-defined Python functions. The keys used in these dicts are
    60    defined in the :ref:`Refinement_recipe` table, below.
    61 
    62 There are several ways to set parameters project using different level objects, as is
    63 are described in sections below, but the simplest way to access parameters and flags
    64 in a project is to use the above routines.
     17Routines for reading, writing, modifying and creating GSAS-II project (.gpx) files
     18without use of the graphical user interface (GUI). This module defines wrapper classes around
     19many types of GSAS-II data representations, including :class:`G2Project`,
     20:class:`G2AtomRecord`, :class:`G2PwdrData`, :class:`G2Phase` and :class:`G2Image`.
     21They all inherit from :class:`G2ObjectWrapper`.
     22
     23GSASIIscriptable offers two ways to use some of GSAS-II's capabilities
     24without use of the graphical user interface: through Python scripts that
     25call the :ref:`API` or via shell/batch commands that use
     26the :ref:`CommandlineInterface`, which provides access a number of features without writing
     27Python scripts.
     28
     29All GSASIIscriptable scripts will need to create a :class:`G2Project` object
     30either for a new GSAS-II project or to read in an existing project (.gpx) file. The most commonly used routines in this object are:
     31
     32    :meth:`G2Project.add_powder_histogram`
     33       Used to read in powder diffraction data to a project file.
     34
     35    :meth:`G2Project.add_simulated_powder_histogram`
     36       Defines a "dummy" powder diffraction data that will be simulated after a refinement step.
     37
     38    :meth:`G2Project.add_image`
     39       Reads in an image to a project.
     40
     41    :meth:`G2Project.add_phase`
     42       Adds a phase to a project
     43
     44    :meth:`G2Project.histograms`
     45       Provides a list of histograms in the current project, as :class:`G2PwdrData` objects
     46
     47    :meth:`G2Project.phases`
     48       Provides a list of phases defined in the current project, as :class:`G2Phase` objects
     49
     50    :meth:`G2Project.images`
     51       Provides a list of images in the current project, as :class:`G2Image` objects
     52
     53    :meth:`G2Project.save`
     54       Writes the current project to disk.
     55
     56    :meth:`G2Project.do_refinements`
     57       This is passed a list of dictionaries, where each dict defines a refinement step.
     58       Passing a list with a single empty dict initiates a refinement with the current
     59       parameters and flags. A refinement dict sets up a single refinement step
     60       (as described in :ref:`Project_dicts`).
     61       It specifies parameter & refinement flag changes, which are usually followed by a
     62       refinement run and optionally by calls to locally-defined Python functions.
     63       The keys used in these refinement dicts are defined in the :ref:`Refinement_recipe`
     64       table, below.
     65
     66    :meth:`G2Project.set_refinement`
     67       This is passed a single dict which is used to set parameters and flags.
     68       These actions can be performed also in :meth:`G2Project.do_refinements`.
     69
     70Images, powder histograms, phases and within phases, atoms, all have their own objects and provide
     71methods for getting and changing settings associated with them. See the classes,
     72:class:`G2PwdrData`, :class:`G2Phase` and :class:`G2Image` for more information.
     73
     74.. _Refinement_dicts:
    6575
    6676=====================
    6777Refinement parameters
    6878=====================
    69 The most complex part of scripting GSAS-II comes in setting up the input to control refinements, which is
    70 described here.
     79The most complex part of scripting GSAS-II refinements
     80comes in setting up the input to control refinements. This input is
     81described immediately below.
    7182
    7283.. _Project_dicts:
     
    529540
    530541The large number of classes and modules in this module are described below.
    531 Most commonly a script will create a G2Project object using :class:`G2Project` and then
    532 perform actions such as
    533 adding a histogram (method :meth:`G2Project.add_powder_histogram`),
     542A script will have one or more G2Project objects using :class:`G2Project` and then
     543perform actions such as adding a histogram (method :meth:`G2Project.add_powder_histogram`),
    534544adding a phase (method :meth:`G2Project.add_phase`),
    535545or setting parameters and performing a refinement
    536546(method :meth:`G2Project.do_refinements`).
    537547
    538 In some cases, it may be easier to use
    539 methods inside :class:`G2PwdrData` or :class:`G2Phase` or these objects
    540 may offer more options.
     548To change settings within hitograms, images and phases, one usually needs to use
     549methods inside :class:`G2PwdrData`, :class:`G2Image` or :class:`G2Phase`.
    541550
    542551---------------------------------------------------------------
     
    31743183class G2Image(G2ObjectWrapper):
    31753184    """Wrapper for an IMG tree entry, containing an image and various metadata.
     3185
     3186    Example:
     3187
     3188    >>> gpx = G2sc.G2Project(filename='itest.gpx')
     3189    >>> img2 = gpx.add_image(idata,fmthint="TIF")
     3190    >>> img2[0].loadControls('stdSettings.imctrl')
     3191    >>> img2[0].setCalibrant('Si    SRM640c')
     3192    >>> img2[0].loadMasks('stdMasks.immask')
     3193    >>> img2[0].Recalibrate()
     3194    >>> img2[0].setControl('outAzimuths',3)
     3195    >>> pwdrList = img2[0].Integrate()
     3196
    31763197    """
    3177     # parameters in
     3198    # parameters in that can be accessed via setControl
    31783199    ControlList = {
    31793200        'int': ['calibskip', 'pixLimit', 'edgemin', 'outChannels',
     
    31923213        }
    31933214    '''Defines the items known to exist in the Image Controls tree section
    3194     and their data types.
    3195     '''
    3196     # special handling: 'background image', 'dark image', 'Gain map',
    3197     #   'calibrant'
    3198 
     3215    and the item's data types. A few are not included
     3216    ('background image', 'dark image', 'Gain map', and 'calibrant') because
     3217    these items have special set routines,
     3218    where references to entries are checked to make sure their values are
     3219    correct.
     3220    '''
     3221    # this may need future attention
     3222       
    31993223    def __init__(self, data, name, proj):
    32003224        self.data = data
     
    32533277        that match the string in arg.
    32543278
    3255           Example: findControl('calib') will return
    3256           [['calibskip', 'int'], ['calibdmin', 'float'], ['calibrant', 'str']]
     3279            Example:
     3280
     3281            >>> findControl('calib')
     3282            [['calibskip', 'int'], ['calibdmin', 'float'], ['calibrant', 'str']]
    32573283
    32583284        :param str arg: a string containing part of the name of a
     
    33483374       
    33493375    def Recalibrate(self):
     3376        '''Invokes a recalibration fit (same as Image Controls/Calibration/Recalibrate
     3377        menu command). Note that for this to work properly, the calibration
     3378        coefficients (center, wavelength, ditance & tilts) must be fairly close.
     3379        This may produce a better result if run more than once.
     3380        '''
    33503381        ImageZ = GetCorrImage(Readers['Image'],self.proj,self)
    33513382        G2img.ImageRecalibrate(None,ImageZ,self.data['Image Controls'],self.data['Masks'])
    3352        
     3383
     3384    def Integrate(self,name=None):
     3385        '''Invokes an image integration (same as Image Controls/Integration/Integrate
     3386        menu command). All parameters will have previously been set with Image Controls
     3387        so no input is needed here. Note that if integration is performed on an
     3388        image more than once, histogram entries may be overwritten. Use the name
     3389        parameter to prevent this if desired.
     3390
     3391        :param str name: base name for created histogram(s). If None (default),
     3392          the histogram name is taken from the image name.
     3393        :returns: a list of created histogram (:class:`G2PwdrData`) objects.
     3394        '''
     3395        ImageZ = GetCorrImage(Readers['Image'],self.proj,self)
     3396        # do integration
     3397        ints,azms,Xvals,cancel = G2img.ImageIntegrate(ImageZ,self.data['Image Controls'],self.data['Masks'])
     3398        # code from here on based on G2IO.SaveIntegration, but places results in the current
     3399        # project rather than tree
     3400        X = Xvals[:-1]
     3401        N = len(X)
     3402
     3403        data = self.data['Image Controls']
     3404        Comments = self.data['Comments']
     3405        # make name from image, unless overridden
     3406        if name:
     3407            if not name.startswith(data['type']+' '):
     3408                name = data['type']+' '+name
     3409        else:
     3410            name = self.name.replace('IMG ',data['type']+' ')
     3411        if 'PWDR' in name:
     3412            if 'target' in data:
     3413                names = ['Type','Lam1','Lam2','I(L2)/I(L1)','Zero','Polariz.','U','V','W','X','Y','Z','SH/L','Azimuth']
     3414                codes = [0 for i in range(14)]
     3415            else:
     3416                names = ['Type','Lam','Zero','Polariz.','U','V','W','X','Y','Z','SH/L','Azimuth']
     3417                codes = [0 for i in range(12)]
     3418        elif 'SASD' in name:
     3419            names = ['Type','Lam','Zero','Azimuth']
     3420            codes = [0 for i in range(4)]
     3421            X = 4.*np.pi*npsind(X/2.)/data['wavelength']    #convert to q
     3422        Xminmax = [X[0],X[-1]]
     3423        Azms = []
     3424        dazm = 0.
     3425        if data['fullIntegrate'] and data['outAzimuths'] == 1:
     3426            Azms = [45.0,]                              #a poor man's average?
     3427        else:
     3428            for i,azm in enumerate(azms[:-1]):
     3429                if azm > 360. and azms[i+1] > 360.:
     3430                    Azms.append(G2img.meanAzm(azm%360.,azms[i+1]%360.))
     3431                else:   
     3432                    Azms.append(G2img.meanAzm(azm,azms[i+1]))
     3433            dazm = np.min(np.abs(np.diff(azms)))/2.
     3434        # pull out integration results and make histograms for each
     3435        IntgOutList = []
     3436        for i,azm in enumerate(azms[:-1]):
     3437            Aname = name+" Azm= %.2f"%((azm+dazm)%360.)
     3438            # MT dict to contain histogram
     3439            HistDict = {}
     3440            histItems = [Aname]
     3441            Sample = G2obj.SetDefaultSample()       #set as Debye-Scherrer
     3442            Sample['Gonio. radius'] = data['distance']
     3443            Sample['Omega'] = data['GonioAngles'][0]
     3444            Sample['Chi'] = data['GonioAngles'][1]
     3445            Sample['Phi'] = data['GonioAngles'][2]
     3446            Sample['Azimuth'] = (azm+dazm)%360.    #put here as bin center
     3447            polariz = 0.99    #set default polarization for synchrotron radiation!
     3448            for item in Comments:
     3449                if 'polariz' in item:
     3450                    try:
     3451                        polariz = float(item.split('=')[1])
     3452                    except:
     3453                        polariz = 0.99
     3454                for key in ('Temperature','Pressure','Time','FreePrm1','FreePrm2','FreePrm3','Omega',
     3455                    'Chi','Phi'):
     3456                    if key.lower() in item.lower():
     3457                        try:
     3458                            Sample[key] = float(item.split('=')[1])
     3459                        except:
     3460                            pass
     3461                if 'label_prm' in item.lower():
     3462                    for num in ('1','2','3'):
     3463                        if 'label_prm'+num in item.lower():
     3464                            Controls['FreePrm'+num] = item.split('=')[1].strip()
     3465            if 'PWDR' in Aname:
     3466                if 'target' in data:    #from lab x-ray 2D imaging data
     3467                    wave1,wave2 = waves[data['target']]
     3468                    parms = ['PXC',wave1,wave2,0.5,0.0,polariz,290.,-40.,30.,6.,-14.,0.0,0.0001,Azms[i]]
     3469                else:
     3470                    parms = ['PXC',data['wavelength'],0.0,polariz,1.0,-0.10,0.4,0.30,1.0,0.0,0.0001,Azms[i]]
     3471            elif 'SASD' in Aname:
     3472                Sample['Trans'] = data['SampleAbs'][0]
     3473                parms = ['LXC',data['wavelength'],0.0,Azms[i]]
     3474            Y = ints[i]
     3475            Ymin = np.min(Y)
     3476            Ymax = np.max(Y)
     3477            W = np.where(Y>0.,1./Y,1.e-6)                    #probably not true
     3478            section = 'Comments'
     3479            histItems += [section]
     3480            HistDict[section] = Comments
     3481            section = 'Limits'
     3482            histItems += [section]
     3483            HistDict[section] = copy.deepcopy([tuple(Xminmax),Xminmax])
     3484            if 'PWDR' in Aname:
     3485                section = 'Background'
     3486                histItems += [section]
     3487                HistDict[section] = [['chebyschev',1,3,1.0,0.0,0.0],
     3488                    {'nDebye':0,'debyeTerms':[],'nPeaks':0,'peaksList':[]}]
     3489            inst = [dict(zip(names,zip(parms,parms,codes))),{}]
     3490            for item in inst[0]:
     3491                inst[0][item] = list(inst[0][item])
     3492            section = 'Instrument Parameters'
     3493            histItems += [section]
     3494            HistDict[section] = inst
     3495            if 'PWDR' in Aname:
     3496                section = 'Sample Parameters'
     3497                histItems += [section]
     3498                HistDict[section] = Sample
     3499                section = 'Peak List'
     3500                histItems += [section]
     3501                HistDict[section] = {'sigDict':{},'peaks':[]}
     3502                section = 'Index Peak List'
     3503                histItems += [section]
     3504                HistDict[section] = [[],[]]
     3505                section = 'Unit Cells List'
     3506                histItems += [section]
     3507                HistDict[section] = []
     3508                section = 'Reflection Lists'
     3509                histItems += [section]
     3510                HistDict[section] = {}
     3511            elif 'SASD' in Aname:             
     3512                section = 'Substances'
     3513                histItems += [section]
     3514                HistDict[section] = G2pdG.SetDefaultSubstances()  # this needs to be moved
     3515                section = 'Sample Parameters'
     3516                histItems += [section]
     3517                HistDict[section] = Sample
     3518                section = 'Models'
     3519                histItems += [section]
     3520                HistDict[section] = G2pdG.SetDefaultSASDModel() # this needs to be moved
     3521            valuesdict = {
     3522                'wtFactor':1.0,'Dummy':False,'ranId':ran.randint(0,sys.maxsize),'Offset':[0.0,0.0],'delOffset':0.02*Ymax,
     3523                'refOffset':-0.1*Ymax,'refDelt':0.1*Ymax,'Yminmax':[Ymin,Ymax]}
     3524            # if Aname is already in the project replace it
     3525            for j in self.proj.names:
     3526                if j[0] == Aname:
     3527                    print('Replacing "{}" in project'.format(Aname))
     3528                    break
     3529            else:
     3530                print('Adding "{}" to project'.format(Aname))
     3531                self.proj.names.append([Aname]+
     3532                        [u'Comments',u'Limits',u'Background',u'Instrument Parameters',
     3533                         u'Sample Parameters', u'Peak List', u'Index Peak List',
     3534                         u'Unit Cells List', u'Reflection Lists'])
     3535            HistDict['data'] = [valuesdict,
     3536                    [np.array(X),np.array(Y),np.array(W),np.zeros(N),np.zeros(N),np.zeros(N)]]
     3537            self.proj.data[Aname] = HistDict
     3538            IntgOutList.append(self.proj.histogram(Aname))
     3539        return IntgOutList
     3540
    33533541##########################
    33543542# Command Line Interface #
Note: See TracChangeset for help on using the changeset viewer.