예제 #1
0
    def makeReader(self):
        """Return a reader instance based on self
"""
        # check validity of input
        self._check()
        #
        # Set up image names in right format
        #
        fullPath = lambda fn: os.path.join(self.imageDir, fn)
        numEmpty = lambda fn: self.imageNameD[fn][0]
        imgInfo = [(fullPath(f), numEmpty(f)) for f in self.imageNames]

        ref_reader = self.RC(imgInfo)
        #
        # Check for omega info
        #
        nfile = len(imgInfo)
        dinfo = [self.imageNameD[f] for f in self.imageNames]
        omin = dinfo[0][1]
        if omin is not None:
            odel = dinfo[nfile - 1][3]
            print "omega min and delta: ", omin, odel
            omargs = (valunits.valWUnit('omin', 'angle', float(omin), 'degrees'),
                      valunits.valWUnit('odel', 'angle', float(odel), 'degrees'))
        else:
            omargs = ()
            pass
        print 'omargs:  ', omargs
        #
        # Dark file
        #
        subDark = not (self.darkMode == ReaderInput.DARK_MODE_NONE)
        if (self.darkMode == ReaderInput.DARK_MODE_FILE):
            drkFile = os.path.join(self.darkDir, self.darkName)
        elif (self.darkMode == ReaderInput.DARK_MODE_ARRAY):
            drkFileName = os.path.join(self.darkDir, self.darkName)
            drkFile     = ref_reader.frame(
                buffer=numpy.fromfile(drkFileName,
                                      dtype=ref_reader.dtypeRead
                                      )
                )
        else:
            drkFile = None
            pass
        #
        # Flip options
        #
        doFlip  = not (self.flipMode == ReaderInput.FLIP_NONE)
        flipArg = ReaderInput.FLIP_DICT[self.flipMode]
        #
        # Make the reader
        #
        print 'reader:  \n', imgInfo, subDark, drkFile, doFlip, flipArg
        r = self.RC(imgInfo, *omargs,
                    subtractDark = subDark,
                    dark         = drkFile,
                    doFlip       = doFlip,
                    flipArg      = flipArg)

        return r
예제 #2
0
def processWavelength(arg):
    """
    Convert an energy value to a wavelength.  If argument has units of length or energy,
    will convert to globally specified unit type for wavelength (dUnit).  If argument
    is a scalar, assumed input units are keV.
    """
    if hasattr(arg, "getVal"):
        if arg.isLength():
            retval = arg.getVal(dUnit)
        elif arg.isEnergy():
            try:
                speed = C.c
                planck = C.h
            except:
                raise NotImplementedError, "scipy does not have constants"
                # speed  = ...
                # planck = ...
            e = arg.getVal("J")
            retval = valunits.valWUnit("wavelength", "length", planck * speed / e, "m").getVal(dUnit)
        else:
            raise RuntimeError, "do not know what to do with " + str(arg)
    else:
        keV2J = 1.0e3 * C.e
        e = keV2J * arg
        retval = valunits.valWUnit("wavelength", "length", C.h * C.c / e, "m").getVal(dUnit)

    return retval
예제 #3
0
파일: experiment.py 프로젝트: B-Rich/hexrd
    def makeReader(self):
        """Return a reader instance based on self
"""
        # check validity of input
        self._check()
        #
        # Set up image names in right format
        #
        fullPath = lambda fn: os.path.join(self.imageDir, fn)
        numEmpty = lambda fn: self.imageNameD[fn][0]
        imgInfo = [(fullPath(f), numEmpty(f)) for f in self.imageNames]

        ref_reader = self.RC(imgInfo)
        #
        # Check for omega info
        #
        nfile = len(imgInfo)
        dinfo = [self.imageNameD[f] for f in self.imageNames]
        omin = dinfo[0][1]
        if omin is not None:
            odel = dinfo[nfile - 1][3]
            print "omega min and delta: ", omin, odel
            omargs = (valunits.valWUnit('omin', 'angle', float(omin), 'degrees'),
                      valunits.valWUnit('odel', 'angle', float(odel), 'degrees'))
        else:
            omargs = ()
            pass
        print 'omargs:  ', omargs
        #
        # Dark file
        #
        subDark = not (self.darkMode == ReaderInput.DARK_MODE_NONE)
        if (self.darkMode == ReaderInput.DARK_MODE_FILE):
            drkFile = os.path.join(self.darkDir, self.darkName)
        elif (self.darkMode == ReaderInput.DARK_MODE_ARRAY):
            drkFileName = os.path.join(self.darkDir, self.darkName)
            drkFile     = ref_reader.frame(
                buffer=numpy.fromfile(drkFileName,
                                      dtype=ref_reader.dtypeRead
                                      )
                )
        else:
            drkFile = None
            pass
        #
        # Flip options
        #
        doFlip  = not (self.flipMode == ReaderInput.FLIP_NONE)
        flipArg = ReaderInput.FLIP_DICT[self.flipMode]
        #
        # Make the reader
        #
        print 'reader:  \n', imgInfo, subDark, drkFile, doFlip, flipArg
        r = self.RC(imgInfo, *omargs,
                    subtractDark = subDark,
                    dark         = drkFile,
                    doFlip       = doFlip,
                    flipArg      = flipArg)

        return r
예제 #4
0
def processWavelength(arg):
    """
    Convert an energy value to a wavelength.  If argument has units of length or energy,
    will convert to globally specified unit type for wavelength (dUnit).  If argument
    is a scalar, assumed input units are keV.
    """
    if hasattr(arg, 'getVal'):
        if arg.isLength():
            retval = arg.getVal(dUnit)
        elif arg.isEnergy():
            try:
                speed  = C.c
                planck = C.h
            except:
                raise NotImplementedError, 'scipy does not have constants'
                # speed  = ...
                # planck = ...
            e = arg.getVal('J')
            retval = valunits.valWUnit('wavelength', 'length', planck*speed/e, 'm').getVal(dUnit)
        else:
            raise RuntimeError, 'do not know what to do with '+str(arg)
    else:
        keV2J = 1.e3*C.e
        e = keV2J * arg
        retval = valunits.valWUnit('wavelength', 'length', C.h*C.c/e, 'm').getVal(dUnit)

    return retval
예제 #5
0
파일: material.py 프로젝트: X-SHI-X/hexrd
 def materials(self):
     """Return a dict of materials."""
     if not hasattr(self, '_materials'):
         self._materials = material.load_materials_hdf5(
             f=self.definitions,
             dmin=valWUnit("dmin", "length", self.dmin, "angstrom"))
     return self._materials
예제 #6
0
    def OnDefaultWavelength(self, e):
        """Make the current wavelength the default for the session"""
        kev = float(self.waveKEV_txt.GetValue())
        Material.DFLT_KEV = valWUnit('wavelength', 'energy', kev, 'keV')
        print 'new default for kev', Material.DFLT_KEV

        return
예제 #7
0
    def __init__(self,
                 material_file=None,
                 material_keys=None,
                 dmin=_nm(0.05),
                 wavelength={
                     'alpha1': [_nm(0.15406), 1.0],
                     'alpha2': [_nm(0.154443), 0.52]
                 }):

        self.phase_dict = {}
        self.num_phases = 0
        """
        set wavelength. check if wavelength is supplied in A, if it is
        convert to nm since the rest of the code assumes those units
        """
        wavelength_nm = {}
        for k, v in wavelength.items():
            wavelength_nm[k] = [
                valWUnit('lp', 'length', v[0].getVal('nm'), 'nm'), v[1]
            ]

        self.wavelength = wavelength_nm

        self.dmin = dmin

        if (material_file is not None):
            if (material_keys is not None):
                if (type(material_keys) is not list):
                    self.add(material_file, material_keys)
                else:
                    self.add_many(material_file, material_keys)
예제 #8
0
 def save(self, filename):
     """
     self.dataStore
     self.planeData
     self.iHKLList
     self.etaEdges
     self.omeEdges
     self.etas
     self.omegas
     """
     args = np.array(self.planeData.getParams())[:4]
     args[2] = valWUnit('wavelength', 'length', args[2], 'angstrom')
     hkls = self.planeData.hkls
     save_dict = {
         'dataStore': self.dataStore,
         'etas': self.etas,
         'etaEdges': self.etaEdges,
         'iHKLList': self.iHKLList,
         'omegas': self.omegas,
         'omeEdges': self.omeEdges,
         'planeData_args': args,
         'planeData_hkls': hkls
     }
     np.savez_compressed(filename, **save_dict)
     return
예제 #9
0
    def OnDefaultWavelength(self, e):
        """Make the current wavelength the default for the session"""
        kev = float(self.waveKEV_txt.GetValue())
        Material.DFLT_KEV = valWUnit('wavelength', 'energy', kev, 'keV')
        print 'new default for kev', Material.DFLT_KEV

        return
예제 #10
0
 def refine_grains(self,
                   minCompl,
                   nSubIter=3,
                   doFit=False,
                   etaTol=valunits.valWUnit('etaTol', 'angle', 1.0,
                                            'degrees'),
                   omeTol=valunits.valWUnit('etaTol', 'angle', 1.0,
                                            'degrees'),
                   fineDspTol=5.0e-3,
                   fineEtaTol=valunits.valWUnit('etaTol', 'angle', 0.5,
                                                'degrees'),
                   fineOmeTol=valunits.valWUnit('etaTol', 'angle', 0.5,
                                                'degrees')):
     """
     refine a grain list
     """
     # refine grains formally using a multi-pass refinement
     nGrains = self.rMats.shape[0]
     grainList = []
     for iG in range(nGrains):
         #indexer.progress_bar(float(iG) / nGrains)
         grain = G.Grain(self.spots_for_indexing,
                         rMat=self.rMats[iG, :, :],
                         etaTol=etaTol,
                         omeTol=omeTol,
                         claimingSpots=False)
         if grain.completeness > minCompl:
             for i in range(nSubIter):
                 grain.fit()
                 s1, s2, s3 = grain.findMatches(etaTol=etaTol,
                                                omeTol=omeTol,
                                                strainMag=fineDspTol,
                                                updateSelf=True,
                                                claimingSpots=False,
                                                doFit=doFit,
                                                testClaims=True)
             if grain.completeness > minCompl:
                 grainList.append(grain)
                 pass
             pass
         pass
     self.grainList = grainList
     self._fitRMats = numpy.array(
         [self.grainList[i].rMat for i in range(len(grainList))])
     return
예제 #11
0
파일: experiment.py 프로젝트: B-Rich/hexrd
 def refine_grains(self,
                   minCompl,
                   nSubIter=3,
                   doFit=False,
                   etaTol=valunits.valWUnit('etaTol', 'angle', 1.0, 'degrees'),
                   omeTol=valunits.valWUnit('etaTol', 'angle', 1.0, 'degrees'),
                   fineDspTol=5.0e-3,
                   fineEtaTol=valunits.valWUnit('etaTol', 'angle', 0.5, 'degrees'),
                   fineOmeTol=valunits.valWUnit('etaTol', 'angle', 0.5, 'degrees')):
     """
     refine a grain list
     """
     # refine grains formally using a multi-pass refinement
     nGrains    = self.rMats.shape[0]
     grainList = []
     for iG in range(nGrains):
         indexer.progress_bar(float(iG) / nGrains)
         grain = G.Grain(self.spots_for_indexing,
                             rMat=self.rMats[iG, :, :],
                             etaTol=etaTol,
                             omeTol=omeTol,
                             claimingSpots=False)
         if grain.completeness > minCompl:
             for i in range(nSubIter):
                 grain.fit()
                 s1, s2, s3 = grain.findMatches(etaTol=etaTol, omeTol=omeTol, strainMag=fineDspTol,
                                                updateSelf=True, claimingSpots=False, doFit=doFit,
                                                testClaims=True)
             if grain.completeness > minCompl:
                 grainList.append(grain)
                 pass
             pass
         pass
     self.grainList = grainList
     self._fitRMats = numpy.array([self.grainList[i].rMat for i in range(len(grainList))])
     return
예제 #12
0
    def add(self, material_file, material_key):
        self[material_key] = {}
        self.num_phases += 1
        for l in self.wavelength:
            lam = self.wavelength[l][0].value * 1e-9
            E = constants.cPlanck * constants.cLight / constants.cCharge / lam
            E *= 1e-3
            kev = valWUnit('beamenergy', 'energy', E, 'keV')
            self[material_key][l] = Material_Rietveld(material_file,
                                                      material_key,
                                                      dmin=self.dmin,
                                                      kev=kev)

        for k in self:
            for l in self.wavelength:
                self[k][l].pf = 1.0 / self.num_phases
예제 #13
0
파일: material.py 프로젝트: X-SHI-X/hexrd
    def _set_beamEnergy(self, keV):
        """
        Set method for beamEnergy

        * note that units are assumed to be keV for
          float arguments.  Also can take a valWUnit
          instance
        """
        if(isinstance(keV, valWUnit)):
            self._beamEnergy = keV
        else:
            self._beamEnergy = valWUnit('kev', 'energy', keV, 'keV')

        ''' 
        acceleration potential is set in volts therefore the factor of 1e3
        @TODO make voltage valWUnit instance so this that we dont have to 
        track this manually inn the future
        '''
        self.unitcell.voltage = self.beamEnergy.value*1e3
        self.planeData.wavelength = keV
        self.update_structure_factor()

        return
예제 #14
0
파일: xrdutil.py 프로젝트: cjh1/hexrd
 def save_eta_ome_maps(eta_ome, filename):
     """
     eta_ome.dataStore
     eta_ome.planeData
     eta_ome.iHKLList
     eta_ome.etaEdges
     eta_ome.omeEdges
     eta_ome.etas
     eta_ome.omegas
     """
     args = np.array(eta_ome.planeData.getParams(), dtype=object)[:4]
     args[2] = valWUnit('wavelength', 'length', args[2], 'angstrom')
     hkls = eta_ome.planeData.hkls
     save_dict = {
         'dataStore': eta_ome.dataStore,
         'etas': eta_ome.etas,
         'etaEdges': eta_ome.etaEdges,
         'iHKLList': eta_ome.iHKLList,
         'omegas': eta_ome.omegas,
         'omeEdges': eta_ome.omeEdges,
         'planeData_args': args,
         'planeData_hkls': hkls
     }
     np.savez_compressed(filename, **save_dict)
예제 #15
0
class Material(object):
    """Simple class for holding lattice parameters, accessible by name.

The class references materials by name and contains lattice and
space group data.
"""
    DFLT_NAME = 'material'
    DFLT_SGNUM = 230
    DFLT_LPARMS = [
        angstroms(1.0),
        angstroms(1.0),
        angstroms(1.0),
        degrees(90.0),
        degrees(90.0),
        degrees(90.0)
    ]
    DFLT_SSMAX = 50

    DFLT_KEV = valWUnit('wavelength', 'energy', 80.725e0, 'keV')
    DFLT_STR = 0.002
    DFLT_TTH = 0.002

    #
    def __init__(self, name=DFLT_NAME, cfgP=None):
        """Constructor for Material

        name -- (str) name of material
        cfgP -- (instance) configuration file parser with
             -- the material name as a section
"""
        #
        self.name = name
        self.description = ''
        #
        if cfgP:
            # Get values from configuration
            self._readCfg(cfgP)
            pass
        else:
            # Use default values
            self._hklMax = Material.DFLT_SSMAX
            self._lparms = Material.DFLT_LPARMS
            self.sgnum = Material.DFLT_SGNUM
            #
            self.description = ''

            pass
        #
        return

    def __str__(self):
        """String representation"""
        s = 'Material:  %s\n' % self.name
        if self.description:
            s += '   description:  %s\n' % self.description
            pass
        s += '   plane Data:  %s' % str(self.planeData)
        return s

    def _readCfg(self, p):
        """Read values from config parser"""

        # Lattice parameters

        lpStrings = (('a-in-angstroms',
                      angstroms), ('b-in-angstroms',
                                   angstroms), ('c-in-angstroms', angstroms),
                     ('alpha-in-degrees',
                      degrees), ('beta-in-degrees',
                                 degrees), ('gamma-in-degrees', degrees))

        sgnum = p.getint(self.name, 'space-group')
        tmpSG = SG(sgnum)

        lparams = []
        for ind in tmpSG.reqParams:
            param, unit = lpStrings[ind]
            lparams.append(unit(p.getfloat(self.name, param)))
            pass

        # Initialize

        self._hklMax = p.getint(self.name, 'hkls-ssmax')
        self._lparms = self._toSixLP(sgnum, lparams)
        self.sgnum = sgnum
        #
        self.description = p.get(self.name, 'description')

        return

    def _newPdata(self):
        """Create a new plane data instance"""
        hkls = numpy.array(self.spaceGroup.getHKLs(self.hklMax)).T
        lprm = [self._lparms[i] for i in self.spaceGroup.reqParams]
        laue = self.spaceGroup.laueGroup
        self._pData = PData(hkls,
                            lprm,
                            laue,
                            Material.DFLT_KEV,
                            Material.DFLT_STR,
                            tThWidth=Material.DFLT_TTH)
        #
        #  Set default exclusions
        #
        dflt_excl = numpy.array(
            [1 for i in range(len(self._pData.exclusions))], dtype=bool)
        dflt_excl[:5] = False
        self._pData.exclusions = dflt_excl

        return

    def _toSixLP(self, sgn, lp):
        """Generate all six lattice parameters, making sure units are attached."""

        tmpSG = SG(sgn)
        lp6 = list(tmpSG.sixLatticeParams(lp))

        for i in range(6):  # make sure angles have attached units
            if not hasattr(lp6[i], 'getVal'):
                if i in range(3):
                    lp6[i] = angstroms(lp6[i])
                else:
                    lp6[i] = degrees(lp6[i])
                    pass
                pass
            pass

        return lp6

    #
    # ============================== API
    #
    #  ========== Properties
    #

    # property:  spaceGroup

    @property
    def spaceGroup(self):
        """(read only) Space group"""
        return self._spaceGroup

    # property:  sgnum

    def _get_sgnum(self):
        """Get method for sgnum"""
        return self._sgnum

    def _set_sgnum(self, v):
        """Set method for sgnum"""
        self._sgnum = v
        self._spaceGroup = SG(self._sgnum)
        self._newPdata()

        return

    sgnum = property(_get_sgnum, _set_sgnum, None, "Space group number")

    # property:  hklMax

    def _get_hklMax(self):
        """Get method for hklMax"""
        return self._hklMax

    def _set_hklMax(self, v):
        """Set method for hklMax"""
        self._hklMax = v
        self._newPdata()  # update planeData
        return

    hklMax = property(_get_hklMax, _set_hklMax, None,
                      "Max sum of squares for HKLs")
    # property:  planeData

    @property
    def planeData(self):
        """(read only) Return the planeData attribute (lattice parameters)"""
        return self._pData

    # property:  latticeParameters

    def _get_latticeParameters(self):
        """Get method for latticeParameters"""
        return self._lparms

    def _set_latticeParameters(self, v):
        """Set method for latticeParameters"""
        self._lparms = self._toSixLP(self.sgnum, v)
        #self._newPdata()
        self.planeData.lparms = v

        return

    lpdoc = r"""Lattice parameters

On output, all six paramters are returned.

On input, either all six or a minimal set is accepted.

The values have units attached, i.e. they are valWunit instances.
"""
    latticeParameters = property(_get_latticeParameters,
                                 _set_latticeParameters, None, lpdoc)

    # property:  "name"

    def _get_name(self):
        """Set method for name"""
        return self._name

    def _set_name(self, v):
        """Set method for name"""
        self._name = v

        return

    name = property(_get_name, _set_name, None, "Name of material")
    #
    #  ========== Methods
    #
    #
    pass  # end class
예제 #16
0
Use the Material class directly for new materials.  Known
materials are defined by name in materialDict.
"""
from ConfigParser import SafeConfigParser as Parser
import numpy

from hexrd.xrd.crystallography import PlaneData as PData
from hexrd.xrd.spacegroup import SpaceGroup as SG

from hexrd.valunits import valWUnit
#
__all__ = ['Material', 'loadMaterialList']
#
# ================================================== Module Data
#
angstroms = lambda x: valWUnit('lp', 'length', x, 'angstrom')
degrees = lambda x: valWUnit('lp', 'angle', x, 'degrees')


#
# ---------------------------------------------------CLASS:  Material
#
class Material(object):
    """Simple class for holding lattice parameters, accessible by name.

The class references materials by name and contains lattice and
space group data.
"""
    DFLT_NAME = 'material'
    DFLT_SGNUM = 230
    DFLT_LPARMS = [
예제 #17
0
            pwA(foundSpotAngs[:,0], foundSpotAngs[:,1], style='gx')
            # alignment is good, but definitely missing somex
            pwB = plotwrap.PlotWrap()
            pwB(predAngles[:,0],    predAngles[:,2],    style='r+')
            pwB(foundSpotAngs[:,0], foundSpotAngs[:,2], style='gx')
            '''

        nSpotsTThAll, nSpotsTThClaimed, numClaimed, numMultiClaimed = spotsForFit.report(
            scaleByMultip=False)
        # iHKL = num.argmax(nSpotsTThAll)
        iHKL = num.where(nSpotsTThAll == num.unique(nSpotsTThAll)[1])[0][0]
        hklListForIndex = [
            tuple(planeData.getHKLs()[iHKL]),
        ]

        etaTol = valunits.valWUnit('etaTol', 'angle', 0.5, 'degrees')
        omeTol = valunits.valWUnit('omeTol', 'angle', 0.5, 'degrees')
        rMat = indexer.fiberSearch(spotsForFit,
                                   hklListForIndex,
                                   iPhase=planeData.phaseID,
                                   nsteps=720,
                                   minCompleteness=0.70,
                                   minPctClaimed=0.75,
                                   friedelOnly=False,
                                   dspTol=None,
                                   etaTol=etaTol,
                                   omeTol=omeTol,
                                   debug=True,
                                   doMultiProc=opts.doMultiProc,
                                   doRefinement=False)
        print 'found %d grains' % (rMat.shape[0])
예제 #18
0
def mockup_experiment():
    # user options
    # each grain is provided in the form of a quaternion.

    # The following array contains the quaternions for the array. Note that the
    # quaternions are in the columns, with the first row (row 0) being the real
    # part w. We assume that we are dealing with unit quaternions

    quats = np.array([[ 0.91836393,  0.90869942],
                      [ 0.33952917,  0.1834835 ],
                      [ 0.17216207,  0.10095837],
                      [ 0.10811041,  0.36111851]])

    n_grains = quats.shape[-1] # last dimension provides the number of grains
    phis = 2.*np.arccos(quats[0, :]) # phis are the angles for the quaternion
    ns = mutil.unitVector(quats[1:, :]) # ns contains the rotation axis as an unit vector
    exp_maps = np.array([phis[i]*ns[:, i] for i in range(n_grains)])
    rMat_c = rot.rotMatOfQuat(quats)

    cvec = np.arange(-25, 26)
    X, Y, Z = np.meshgrid(cvec, cvec, cvec)

    crd0 = 1e-3*np.vstack([X.flatten(), Y.flatten(), Z.flatten()]).T
    crd1 = crd0 + np.r_[0.100, 0.100, 0]
    crds = np.array([crd0, crd1])

    # make grain parameters
    grain_params = []
    for i in range(n_grains):
        for j in range(len(crd0)):
            grain_params.append(
                np.hstack([exp_maps[i, :], crds[i][j, :], xf.vInv_ref.flatten()])
            )

    # scan range and period
    ome_period = (0, 2*np.pi)
    ome_range = [ome_period,]
    ome_step = np.radians(1.)
    nframes = 0
    for i in range(len(ome_range)):
        del_ome = ome_range[i][1]-ome_range[i][0]
        nframes += int((ome_range[i][1]-ome_range[i][0])/ome_step)

    ome_edges = np.arange(nframes+1)*ome_step

    # instrument
    with open('./retiga.yml', 'r') as fildes:
        instr_cfg = yaml.load(fildes)

    tiltAngles = instr_cfg['detector']['transform']['tilt_angles']
    tVec_d = np.array(instr_cfg['detector']['transform']['t_vec_d']).reshape(3,1)
    chi = instr_cfg['oscillation_stage']['chi']
    tVec_s = np.array(instr_cfg['oscillation_stage']['t_vec_s']).reshape(3,1)
    rMat_d = xfcapi.makeDetectorRotMat(tiltAngles)
    rMat_s = xfcapi.makeOscillRotMat([chi, 0.])

    pixel_size = instr_cfg['detector']['pixels']['size']
    nrows = instr_cfg['detector']['pixels']['rows']
    ncols = instr_cfg['detector']['pixels']['columns']

    col_ps = pixel_size[1]
    row_ps = pixel_size[0]

    row_dim = row_ps*nrows # in mm
    col_dim = col_ps*ncols # in mm
    panel_dims = [(-0.5*ncols*col_ps, -0.5*nrows*row_ps),
                  ( 0.5*ncols*col_ps,  0.5*nrows*row_ps)]

    x_col_edges = col_ps * (np.arange(ncols + 1) - 0.5*ncols)
    y_row_edges = row_ps * (np.arange(nrows, -1, -1) - 0.5*nrows)
    #x_col_edges = np.arange(panel_dims[0][0], panel_dims[1][0] + 0.5*col_ps, col_ps)
    #y_row_edges = np.arange(panel_dims[0][1], panel_dims[1][1] + 0.5*row_ps, row_ps)
    rx, ry = np.meshgrid(x_col_edges, y_row_edges)

    gcrds = xfcapi.detectorXYToGvec(np.vstack([rx.flatten(), ry.flatten()]).T,
                                    rMat_d, rMat_s,
                                    tVec_d, tVec_s, np.zeros(3))

    max_pixel_tth = np.amax(gcrds[0][0])
    detector_params = np.hstack([tiltAngles, tVec_d.flatten(), chi,
                                 tVec_s.flatten()])
    distortion = None

    # a different parametrization for the sensor (makes for faster quantization)
    base = np.array([x_col_edges[0],
                     y_row_edges[0],
                     ome_edges[0]])
    deltas = np.array([x_col_edges[1] - x_col_edges[0],
                       y_row_edges[1] - y_row_edges[0],
                       ome_edges[1] - ome_edges[0]])
    inv_deltas = 1.0/deltas
    clip_vals = np.array([ncols, nrows])



    # dilation
    max_diameter = np.sqrt(3)*0.005
    row_dilation = np.ceil(0.5 * max_diameter/row_ps)
    col_dilation = np.ceil(0.5 * max_diameter/col_ps)

    # crystallography data
    from hexrd import valunits
    gold = material.Material('gold')
    gold.sgnum = 225
    gold.latticeParameters = [4.0782, ]
    gold.hklMax = 200
    gold.beamEnergy = valunits.valWUnit("wavelength", "ENERGY", 52, "keV")
    gold.planeData.exclusions = None
    gold.planeData.tThMax = max_pixel_tth #note this comes from info in the detector


    ns = argparse.Namespace()
    # grains related information
    ns.n_grains = n_grains # this can be derived from other values...
    ns.rMat_c = rMat_c # n_grains rotation matrices (one per grain)
    ns.exp_maps = exp_maps # n_grains exp_maps -angle * rotation axis- (one per grain)

    ns.plane_data = gold.planeData
    ns.detector_params = detector_params
    ns.pixel_size = pixel_size
    ns.ome_range = ome_range
    ns.ome_period = ome_period
    ns.x_col_edges = x_col_edges
    ns.y_row_edges = y_row_edges
    ns.ome_edges = ome_edges
    ns.ncols = ncols
    ns.nrows = nrows
    ns.nframes = nframes # used only in simulate...
    ns.rMat_d = rMat_d
    ns.tVec_d = tVec_d
    ns.chi = chi # note this is used to compute S... why is it needed?
    ns.tVec_s = tVec_s
    # ns.rMat_s = rMat_s
    # ns.tVec_s = tVec_s
    ns.rMat_c = rMat_c
    ns.row_dilation = row_dilation
    ns.col_dilation = col_dilation
    ns.distortion = distortion
    ns.panel_dims = panel_dims # used only in simulate...
    ns.base = base
    ns.inv_deltas = inv_deltas
    ns.clip_vals = clip_vals

    return grain_params, ns
예제 #19
0
            pwA(foundSpotAngs[:,0], foundSpotAngs[:,1], style='gx')
            # alignment is good, but definitely missing somex
            pwB = plotwrap.PlotWrap()
            pwB(predAngles[:,0],    predAngles[:,2],    style='r+')
            pwB(foundSpotAngs[:,0], foundSpotAngs[:,2], style='gx')
            '''

        nSpotsTThAll, nSpotsTThClaimed, numClaimed, numMultiClaimed = spotsForFit.report(
            scaleByMultip=False)
        # iHKL = num.argmax(nSpotsTThAll)
        iHKL = num.where(nSpotsTThAll == num.unique(nSpotsTThAll)[1])[0][0]
        hklListForIndex = [
            tuple(planeData.getHKLs()[iHKL]),
        ]

        etaTol = valunits.valWUnit('etaTol', 'angle', 0.5, 'degrees')
        omeTol = valunits.valWUnit('omeTol', 'angle', 0.5, 'degrees')
        rMat = indexer.fiberSearch(spotsForFit,
                                   hklListForIndex,
                                   iPhase=planeData.phaseID,
                                   nsteps=720,
                                   minCompleteness=0.70,
                                   minPctClaimed=0.75,
                                   friedelOnly=False,
                                   dspTol=None,
                                   etaTol=etaTol,
                                   omeTol=omeTol,
                                   debug=True,
                                   doMultiProc=opts.doMultiProc,
                                   doRefinement=False)
        print 'found %d grains' % (rMat.shape[0])
예제 #20
0
def _angstroms(x):
    return valWUnit('lp', 'length', x, 'angstrom')
예제 #21
0
 def _nm(x):
     return valWUnit('lp', 'length', x, 'nm')
예제 #22
0
class Material(object):
    """Simple class for holding lattice parameters, accessible by name.

    The class references materials by name and contains lattice and
    space group data.
    default data is for nickel, but name is material
    """
    DFLT_NAME = 'material.xtal'
    DFLT_XTAL = 'Ni'
    DFLT_SGNUM = 225

    DFLT_LPARMS = [
        _angstroms(3.61),
        _angstroms(3.61),
        _angstroms(3.61),
        _degrees(90.0),
        _degrees(90.0),
        _degrees(90.0)
    ]
    DFLT_SSMAX = 100

    DFLT_KEV = valWUnit('wavelength', 'energy', 80.725e0, 'keV')
    DFLT_STR = 0.0025
    DFLT_TTH = numpy.radians(0.25)
    DFLT_TTHMAX = numpy.radians(160.0)
    """
    ATOMINFO    Fractional Atom Position of an atom in the unit cell followed by the
    site occupany and debye waller (U) factor in A^(-2)
    B is related to U by B = 8 pi^2 U

    ATOMTYPE    atomic number of all the different species in the unitcell
    """
    DFLT_ATOMINFO = numpy.array([[0., 0., 0., 1.]])
    DFLT_U = numpy.array([4.18e-7])
    DFLT_ATOMTYPE = numpy.array([28])
    '''
    the dmin parameter is used to figure out the maximum sampling for g-vectors
    this parameter is in angstroms
    '''
    DFLT_DMIN = _angstroms(1.0)
    '''
    some materials have more than one space group setting. for ex
    the diamond cubic system has two settings with the origin either
    at (0,0,0) or at (1/4,1/4,1/4) etc. this handle takes care of these
    cases. but the defaiult is always 0

    default space group setting
    '''
    DFLT_SGSETTING = 0

    def __init__(self,
                 name=None,
                 material_file=None,
                 dmin=DFLT_DMIN,
                 kev=DFLT_KEV,
                 sgsetting=DFLT_SGSETTING):
        """Constructor for Material

        name -- (str) name of crystal
        material_file -- (str) name of the material file
        which contains the crystal. this could be either cif
        or hdf5
        """
        self.name = name
        self.description = ''

        self._dmin = dmin

        self._beamEnergy = kev

        self.sgsetting = sgsetting

        if material_file:
            # Get values from configuration
            # self._readCfg(material_file)
            # >> @ date 08/20/2020 SS removing dependence on hklmax
            #self._hklMax = Material.DFLT_SSMAX
            # self._beamEnergy = Material.DFLT_KEV
            form = Path(material_file).suffix[1:]

            if (form == 'cif'):
                self._readCif(material_file)
            elif (form in ['h5', 'hdf5', 'xtal']):
                self._readHDFxtal(fhdf=material_file, xtal=name)
        else:
            # Use default values
            self._lparms = Material.DFLT_LPARMS
            # self._hklMax = Material.DFLT_SSMAX
            #
            self.description = ''
            #
            self.sgnum = Material.DFLT_SGNUM
            self._sgsetting = Material.DFLT_SGSETTING
            #
            self._atominfo = Material.DFLT_ATOMINFO
            #
            self._U = Material.DFLT_U
            #
            self._atomtype = Material.DFLT_ATOMTYPE
            #

        self.unitcell = unitcell.unitcell(self._lparms, self.sgnum,
                                          self._atomtype, self._atominfo,
                                          self._U, self._dmin.getVal('nm'),
                                          self._beamEnergy.value,
                                          self._sgsetting)

        self._newPdata()
        self.update_structure_factor()

    def __str__(self):
        """String representation"""
        s = 'Material:  %s\n' % self.name
        if self.description:
            s += '   description:  %s\n' % self.description
            pass
        s += '   plane Data:  %s' % str(self.planeData)
        return s

    def _newPdata(self):
        """Create a new plane data instance"""
        # spaceGroup module calulates forbidden reflections
        '''
        >> @date 08/20/2020 SS removing dependence of planeData
        initialization on the spaceGroup module. everything is
        initialized using the unitcell module now
        '''
        hkls = self.unitcell.getHKLs(self._dmin.getVal('nm')).T
        lprm = [
            self._lparms[i]
            for i in unitcell._rqpDict[self.unitcell.latticeType][0]
        ]
        laue = self.unitcell._laueGroup
        self._pData = PData(hkls,
                            lprm,
                            laue,
                            self._beamEnergy,
                            Material.DFLT_STR,
                            tThWidth=Material.DFLT_TTH,
                            tThMax=Material.DFLT_TTHMAX)
        '''
          Set default exclusions
          all reflections with two-theta smaller than 90 degrees
        '''
        tth = numpy.array(
            [hkldata['tTheta'] for hkldata in self._pData.hklDataList])

        dflt_excl = numpy.ones(tth.shape, dtype=numpy.bool)
        dflt_excl[~numpy.isnan(tth)] = ~( (tth[~numpy.isnan(tth)] >= 0.0) & \
                                     (tth[~numpy.isnan(tth)] <= numpy.pi/2.0) )
        dflt_excl[0] = False
        self._pData.exclusions = dflt_excl

        return

    def update_structure_factor(self):
        hkls = self.planeData.getHKLs(allHKLs=True)
        sf = numpy.zeros([
            hkls.shape[0],
        ])
        for i, g in enumerate(hkls):
            sf[i] = self.unitcell.CalcXRSF(g)

        self.planeData.set_structFact(sf[~self.planeData.exclusions])

    def _readCif(self, fcif=DFLT_NAME + '.cif'):
        """
        >> @AUTHOR:     Saransh Singh, Lawrence Livermore National Lab, [email protected]
        >> @DATE:       10/16/2019 SS 1.0 original
        >> @DETAILS:    hexrd3 will have real structure factors and will require the overhaul
                        of the crystallography. In this effort, we will have a cif reader and
                        also the HDF5 format reader in the material class. We will be using
                        pycifrw for i/o
        """

        # make sure file exists etc.
        if (fcif == Material.DFLT_NAME + '.cif'):
            try:
                cif = ReadCif(fcif)
            except (OSError):
                raise RuntimeError(
                    'OS Error: No file name supplied and default file name not found.'
                )
        else:
            try:
                cif = ReadCif(fcif)
            except (OSError):
                raise RuntimeError('OS Error: File not found')

        # read the file
        for k in cif.keys():
            if ('_cell_length_a' in cif[k]):
                m = k
                break
        cifdata = cif[m]
        # cifdata = cif[cif.keys()[0]]

        # make sure the space group is present in the cif file, either as
        # international table number, hermann-maguain or hall symbol
        sgkey = [
            '_space_group_IT_number', '_symmetry_space_group_name_h-m',
            '_symmetry_space_group_name_hall', '_symmetry_Int_Tables_number'
        ]

        sgdata = False
        for key in sgkey:
            sgdata = sgdata or (key in cifdata)
            if (sgdata):
                skey = key
                break

        if (not (sgdata)):
            raise RuntimeError(' No space group information in CIF file! ')

        sgnum = 0
        if skey is sgkey[0]:
            sgnum = int(cifdata[sgkey[0]])
        elif (skey is sgkey[1]):
            HM = cifdata[sgkey[1]]
            HM = HM.replace(" ", "")
            sgnum = HM_to_sgnum[HM]
        elif (skey is sgkey[2]):
            hall = cifdata[sgkey[2]]
            hall = hall.replace(" ", "")
            sgnum = Hall_to_sgnum[HM]
        elif (skey is sgkey[3]):
            sgnum = int(cifdata[sgkey[3]])

        # lattice parameters
        lparms = []
        lpkey = ['_cell_length_a', '_cell_length_b', \
                 '_cell_length_c', '_cell_angle_alpha', \
                 '_cell_angle_beta', '_cell_angle_gamma']

        for key in lpkey:
            n = cifdata[key].find('(')
            if (n != -1):
                lparms.append(float(cifdata[key][:n]))
            else:
                lparms.append(float(cifdata[key]))

        for i in range(6):
            if (i < 3):
                lparms[i] = _angstroms(lparms[i])
            else:
                lparms[i] = _degrees(lparms[i])

        self._lparms = lparms
        self.sgnum = sgnum

        # fractional atomic site, occ and vibration amplitude
        fracsitekey = ['_atom_site_fract_x', '_atom_site_fract_y',\
                        '_atom_site_fract_z',]

        occ_U       = ['_atom_site_occupancy',\
                        '_atom_site_u_iso_or_equiv','_atom_site_U_iso_or_equiv']

        sitedata = True
        for key in fracsitekey:
            sitedata = sitedata and (key in cifdata)

        if (not (sitedata)):
            raise RuntimeError(
                ' fractional site position is not present or incomplete in the CIF file! '
            )

        atompos = []
        for key in fracsitekey:
            slist = cifdata[key]
            pos = []

            for p in slist:
                n = p.find('(')

                if (n != -1):
                    pos.append(p[:n])
                else:
                    pos.append(p)
            '''
            sometimes cif files have negative values so need to
            bring them back to fractional coordinates between 0-1
            '''
            pos = numpy.asarray(pos).astype(numpy.float64)
            pos, _ = numpy.modf(pos + 100.0)
            atompos.append(pos)
        """note that the vibration amplitude, U is just the amplitude (in A)
            to convert to the typical B which occurs in the debye-waller factor,
            we will use the following formula
            B = 8 * pi ^2 * < U_av^2 >
            this will be done here so we dont have to worry about it later
        """

        pocc = (occ_U[0] in cifdata.keys())
        pU = (occ_U[1] in cifdata.keys()) or (occ_U[2] in cifdata.keys())

        if (not pocc):
            warn('occupation fraction not present. setting it to 1')
            occ = numpy.ones(atompos[0].shape)
            atompos.append(occ)
        else:
            slist = cifdata[occ_U[0]]
            occ = []
            for p in slist:
                n = p.find('(')

                if (n != -1):
                    occ.append(p[:n])
                else:
                    occ.append(p)

            atompos.append(numpy.asarray(occ).astype(numpy.float64))

        if (not pU):
            warn(
                'Debye-Waller factors not present. setting to same values for all atoms.'
            )
            U = 1.0 / numpy.pi / 2. / numpy.sqrt(2.) * numpy.ones(
                atompos[0].shape)
            self._U = U
        else:
            if (occ_U[1] in cifdata.keys()):
                k = occ_U[1]
            else:
                k = occ_U[2]

            slist = cifdata[k]
            U = []
            for p in slist:
                n = p.find('(')

                if (n != -1):
                    U.append(p[:n])
                else:
                    U.append(p)

            self._U = numpy.asarray(U).astype(numpy.float64)
        '''
        format everything in the right shape etc.
        '''
        self._atominfo = numpy.asarray(atompos).T
        '''
        get atome types here i.e. the atomic number of atoms at each site
        '''
        atype = '_atom_site_type_symbol'
        patype = (atype in cifdata)
        if (not patype):
            raise RuntimeError('atom types not defined in cif file.')

        satype = cifdata[atype]
        atomtype = []

        for s in satype:
            atomtype.append(ptable[s])

        self._atomtype = numpy.asarray(atomtype).astype(numpy.int32)
        self._sgsetting = 0

    def _readHDFxtal(self, fhdf=DFLT_NAME, xtal=DFLT_NAME):
        """
        >> @AUTHOR:     Saransh Singh, Lawrence Livermore National Lab, [email protected]
        >> @DATE:       10/17/2019 SS 1.0 original
        >> @DETAILS:    hexrd3 will have real structure factors and will require the overhaul
                        of the crystallography. In this effort, we will have a HDF file reader.
                        the file will be the same as the EMsoft xtal file. h5py will be used for
                        i/o
        """

        fexist = path.exists(fhdf)
        if (fexist):
            fid = h5py.File(fhdf, 'r')
            xtal = "/" + xtal
            if xtal not in fid:
                raise IOError('crystal doesn' 't exist in material file.')
        else:
            raise IOError('material file does not exist.')

        gid = fid.get(xtal)

        sgnum       = numpy.asscalar(numpy.array(gid.get('SpaceGroupNumber'), \
                                    dtype = numpy.int32))
        """
            IMPORTANT NOTE:
            note that the latice parameters is nm by default
            hexrd on the other hand uses A as the default units, so we
            need to be careful and convert it right here, so there is no
            confusion later on
        """
        lparms = list(gid.get('LatticeParameters'))

        for i in range(6):
            if (i < 3):
                lparms[i] = _angstroms(lparms[i] * 10.0)
            else:
                lparms[i] = _degrees(lparms[i])

        self._lparms = lparms
        #self._lparms    = self._toSixLP(sgnum, lparms)
        # fill space group and lattice parameters
        self.sgnum = sgnum

        # the U factors are related to B by the relation B = 8pi^2 U
        self._atominfo = numpy.transpose(
            numpy.array(gid.get('AtomData'), dtype=numpy.float64))
        self._U = numpy.transpose(
            numpy.array(gid.get('U'), dtype=numpy.float64))

        # read atom types (by atomic number, Z)
        self._atomtype = numpy.array(gid.get('Atomtypes'), dtype=numpy.int32)
        self._atom_ntype = self._atomtype.shape[0]

        self._sgsetting = numpy.asscalar(numpy.array(gid.get('SpaceGroupSetting'), \
                                        dtype = numpy.int32))

        fid.close()

    def dump_material(self, filename):
        '''
        get the atominfo dictionaary aand the lattice parameters
        '''
        AtomInfo = {}

        AtomInfo['file'] = filename
        AtomInfo['xtalname'] = self.name
        AtomInfo['xtal_sys'] = xtal_sys_dict[self.unitcell.latticeType.lower()]
        AtomInfo['Z'] = self.unitcell.atom_type
        AtomInfo['SG'] = self.unitcell.sgnum
        AtomInfo['SGsetting'] = self.unitcell.sgsetting
        AtomInfo['APOS'] = self.unitcell.atom_pos
        AtomInfo['U'] = self.unitcell.U
        '''
        lattice parameters
        '''
        lat_param = {
            'a': self.unitcell.a,
            'b': self.unitcell.b,
            'c': self.unitcell.c,
            'alpha': self.unitcell.alpha,
            'beta': self.unitcell.beta,
            'gamma': self.unitcell.gamma
        }

        Write2H5File(AtomInfo, lat_param)

    # ============================== API
    #
    #  ========== Properties
    #

    # property:  spaceGroup

    @property
    def spaceGroup(self):
        """(read only) Space group"""
        return self._spaceGroup

    @property
    def vol(self):
        return self.unitcell.vol

    # property:  sgnum

    def _get_sgnum(self):
        """Get method for sgnum"""
        return self._sgnum

    def _set_sgnum(self, v):
        """Set method for sgnum
        >> @date 08/20/2020 SS removed planedata initialization
            everytime sgnum is updated singe everything is initialized
            using unitcell now
        """
        self._sgnum = v

        # Update the unit cell if there is one
        if hasattr(self, 'unitcell'):
            self.unitcell.sgnum = v

    sgnum = property(_get_sgnum, _set_sgnum, None, "Space group number")

    # property:  beamEnergy

    def _get_beamEnergy(self):
        """Get method for beamEnergy"""
        return self._beamEnergy

    def _set_beamEnergy(self, keV):
        """
        Set method for beamEnergy

        * note that units are assumed to be keV for
          float arguments.  Also can take a valWUnit
          instance
        """
        self._beamEnergy = keV
        self.planeData.wavelength = keV

        return

    beamEnergy = property(_get_beamEnergy, _set_beamEnergy, None,
                          "Beam energy in keV")

    #>> @date 08/20/2020 removing dependence on hklmax
    # property:  hklMax

    # def _get_hklMax(self):
    #     """Get method for hklMax"""
    #     return self._hklMax

    # def _set_hklMax(self, v):
    #     """Set method for hklMax"""
    #     self._hklMax = v
    #     self._newPdata()  # update planeData
    #     return

    # hklMax = property(_get_hklMax, _set_hklMax, None,
    #                   "Max sum of squares for HKLs")
    # property:  planeData

    @property
    def planeData(self):
        """(read only) Return the planeData attribute (lattice parameters)"""
        return self._pData

    # property:  latticeParameters

    def _get_latticeParameters(self):
        """Get method for latticeParameters"""
        return self._lparms

    def _set_latticeParameters(self, v):
        """Set method for latticeParameters"""
        if (len(v) != 6):
            v = unitcell._rqpDict[self.unitcell.latticeType][1](v)
        lp = [_angstroms(v[i]) for i in range(3)]
        for i in range(3, 6):
            lp.append(_degrees(v[i]))
        self._lparms = lp

        rq_lp = unitcell._rqpDict[self.unitcell.latticeType][0]
        for i, vv in enumerate(lp):
            if (vv.isLength()):
                val = vv.value / 10.0
            else:
                val = vv.value
            setattr(self.unitcell, unitcell._lpname[i], val)
        v2 = [lp[x].value for x in rq_lp]
        self.planeData.lparms = v2

        return

    lpdoc = r"""Lattice parameters

On output, all six paramters are returned.

On input, either all six or a minimal set is accepted.

The values have units attached, i.e. they are valWunit instances.
"""
    latticeParameters = property(_get_latticeParameters,
                                 _set_latticeParameters, None, lpdoc)

    # property:  "name"

    def _get_name(self):
        """Set method for name"""
        return self._name

    def _set_name(self, v):
        """Set method for name"""
        self._name = v

        return

    name = property(_get_name, _set_name, None, "Name of material")

    @property
    def dmin(self):
        return self._dmin

    @dmin.setter
    def dmin(self, v):
        if self._dmin == v:
            return

        self._dmin = v

        # Update the unit cell
        self.unitcell.dmin = v.getVal('nm')

        self._newPdata()
        self.update_structure_factor()

    # property: "atominfo"
    def _get_atominfo(self):
        """Set method for name"""
        return self._atominfo

    def _set_atominfo(self, v):
        """Set method for name"""
        if v.shape[1] == 4:
            self._atominfo = v
        else:
            print("Improper syntax, array must be n x 4")

        return

    atominfo = property(
        _get_atominfo, _set_atominfo, None,
        "Information about atomic positions and electron number")

    #
    #  ========== Methods
    #
    #
    pass  # end class
예제 #23
0
파일: material.py 프로젝트: HEXRD/hexrd
 def beam_energy(self, x):
     if not isinstance(x, valWUnit):
         x = valWUnit("beam energy", "energy", x, "keV")
     for matl in self.materials.values():
         matl.beamEnergy = x
예제 #24
0
class Material(object):
    """Simple class for holding lattice parameters, accessible by name.

    The class references materials by name and contains lattice and
    space group data.
    default data is for nickel, but name is material
    """
    DFLT_NAME = 'material.xtal'
    DFLT_XTAL = 'Ni'
    DFLT_SGNUM = 225
    '''
    some materials have more than one space group setting. for ex
    the diamond cubic system has two settings with the origin either
    at (0,0,0) or at (1/4,1/4,1/4) etc. this handle takes care of these
    cases. but the defaiult is always 1
    '''
    DFLT_SGSETTING = 1

    DFLT_LPARMS = [_angstroms(3.61), _angstroms(3.61), _angstroms(3.61),
                   _degrees(90.0), _degrees(90.0), _degrees(90.0)]
    DFLT_SSMAX = 100

    DFLT_KEV = valWUnit('wavelength', 'energy', 80.725e0, 'keV')
    DFLT_STR = 0.0025
    DFLT_TTH = numpy.radians(0.25)
    DFLT_TTHMAX = numpy.radians(160.0)
    """
    ATOMINFO    Fractional Atom Position of an atom in the unit cell followed by the
    site occupany and debye waller (B) factor in nm^(-2)

    ATOMTYPE    atomic number of all the different species in the unitcell
    """
    DFLT_ATOMINFO = numpy.array([[0, 0, 0, 1, 0.033]])    
    DFLT_ATOMTYPE = numpy.array([28])

    '''
    the dmin parameter is used to figure out the maximum sampling for g-vectors
    this parameter is in angstroms
    '''
    DFLT_DMIN = _angstroms(0.2)

    '''
    default space group setting
    '''
    DFLT_SGSETTING = 0

    def __init__(self, name=None, cfgP=None, dmin=DFLT_DMIN, kev=DFLT_KEV, sgsetting=DFLT_SGSETTING):
        """Constructor for Material

        name -- (str) name of material
        cfgP -- (instance) configuration file parser with
             -- the material name as a section
        """
        self.name = name
        self.description = ''
        
        self._dmin = dmin

        self._beamEnergy = kev
        
        self.sgsetting = sgsetting

        if(self._dmin.unit == 'angstrom'):
            # convert to nm
            uc_dmin = self._dmin.value * 0.1

        elif(self._dmin.unit == 'nm'):
            uc_dmin = self._dmin.value

        if cfgP:
            # Get values from configuration
            # self._readCfg(cfgP)
            self._hklMax = Material.DFLT_SSMAX
            # self._beamEnergy = Material.DFLT_KEV
            n = cfgP.find('.')
            form = cfgP[n+1:]

            if(form == 'cif'):
                self._readCif(cfgP)
            elif(form in ['h5', 'hdf5', 'xtal']):
                self._readHDFxtal(fhdf=cfgP, xtal=name)
        else:
            # Use default values
            self._lparms = Material.DFLT_LPARMS
            self._hklMax = Material.DFLT_SSMAX
            #
            self.description = ''
            #
            self.sgnum = Material.DFLT_SGNUM
            self._sgsetting = Material.DFLT_SGSETTING
            #
            self._atominfo = Material.DFLT_ATOMINFO
            #
            self._atomtype = Material.DFLT_ATOMTYPE
            #

        self.unitcell = unitcell(self._lparms, self.sgnum, self._atomtype,
                                self._atominfo, self._U, uc_dmin, 
                                self._beamEnergy.value, self._sgsetting)

        hkls = self.planeData.getHKLs(allHKLs=True)
        sf = numpy.zeros([hkls.shape[0],])
        for i,g in enumerate(hkls):
            sf[i] = self.unitcell.CalcXRSF(g)

        self.planeData.set_structFact(sf[~self.planeData.exclusions])

        return

    def __str__(self):
        """String representation"""
        s = 'Material:  %s\n' % self.name
        if self.description:
            s += '   description:  %s\n' % self.description
            pass
        s += '   plane Data:  %s' % str(self.planeData)
        return s

    def _readCfg(self, p):
        """Read values from config parser"""

        # Lattice parameters

        lpStrings = (
            ('a-in-angstroms', _angstroms),
            ('b-in-angstroms', _angstroms),
            ('c-in-angstroms', _angstroms),
            ('alpha-in-degrees', _degrees),
            ('beta-in-degrees',  _degrees),
            ('gamma-in-degrees', _degrees)
            )

        sgnum = p.getint(self.name, 'space-group')
        tmpSG = SG(sgnum)

        try:
            hklMax = p.getint(self.name, 'hkls-ssmax')
        except:
            hklMax = Material.DFLT_SSMAX

        try:
            beamEnergy = p.getfloat(self.name, 'beam-energy')
        except:
            beamEnergy = Material.DFLT_KEV

        lparams = []
        for ind in tmpSG.reqParams:
            param, unit = lpStrings[ind]
            lparams.append(unit(p.getfloat(self.name, param)))
            pass

        # Initialize
        self._hklMax = hklMax
        self._beamEnergy = beamEnergy
        self._lparms = self._toSixLP(sgnum, lparams)
        self.sgnum = sgnum
        self.description = p.get(self.name, 'description')

        return

    def _newPdata(self):
        """Create a new plane data instance"""
        # spaceGroup module calulates forbidden reflections
        hkls = numpy.array(self.spaceGroup.getHKLs(self.hklMax)).T
        lprm = [self._lparms[i] for i in self.spaceGroup.reqParams]
        laue = self.spaceGroup.laueGroup
        self._pData = PData(hkls, lprm, laue,
                            self._beamEnergy, Material.DFLT_STR,
                            tThWidth=Material.DFLT_TTH,
                            tThMax=Material.DFLT_TTHMAX)
        '''
          Set default exclusions
          all reflections with two-theta smaller than 90 degrees
        '''
        tth = numpy.array([hkldata['tTheta'] for hkldata in self._pData.hklDataList])

        dflt_excl = numpy.ones(tth.shape,dtype=numpy.bool)
        dflt_excl[~numpy.isnan(tth)] = ~( (tth[~numpy.isnan(tth)] >= 0.0) & \
                                     (tth[~numpy.isnan(tth)] <= numpy.pi/2.0) )
        self._pData.exclusions = dflt_excl

        return

    def _toSixLP(self, sgn, lp):
        """
        Generate all six lattice parameters, making sure units are attached.
        """
        tmpSG = SG(sgn)
        lp6 = list(tmpSG.sixLatticeParams(lp))

        # make sure angles have attached units
        for i in range(6):
            if not hasattr(lp6[i], 'getVal'):
                if i in range(3):
                    lp6[i] = _angstroms(lp6[i])
                else:
                    lp6[i] = _degrees(lp6[i])
                    pass
                pass
            pass

        return lp6


    def _readCif(self, fcif=DFLT_NAME+'.cif'):
        """
        >> @AUTHOR:     Saransh Singh, Lawrence Livermore National Lab, [email protected]
        >> @DATE:       10/16/2019 SS 1.0 original
        >> @DETAILS:    hexrd3 will have real structure factors and will require the overhaul
                        of the crystallography. In this effort, we will have a cif reader and
                        also the HDF5 format reader in the material class. We will be using 
                        pycifrw for i/o
        """

        # make sure file exists etc.
        if(fcif == Material.DFLT_NAME+'.cif'):
            try:
                cif = ReadCif(fcif)
            except(OSError):
                raise RuntimeError('OS Error: No file name supplied and default file name not found.')
        else:
            try:
                cif = ReadCif(fcif)
            except(OSError):
                raise RuntimeError('OS Error: File not found')

        # read the file
        cifdata = cif[cif.keys()[0]]

        # make sure the space group is present in the cif file, either as 
        # international table number, hermann-maguain or hall symbol
        sgkey = ['_space_group_IT_number', '_symmetry_space_group_name_h-m', \
                 '_symmetry_space_group_name_hall']

        sgdata = False
        for key in sgkey:
            sgdata = sgdata or (key in cifdata)
            if(sgdata):
                skey = key
                break

        if(not(sgdata)):
            raise RuntimeError(' No space group information in CIF file! ')

        sgnum = 0
        if skey is sgkey[0]:
            sgnum = int(cifdata[sgkey[0]])
        elif (skey is sgkey[1]):
            HM = cifdata[sgkey[1]]
            sgnum = sg.HM_to_sgnum[HM]
        elif (skey is sgkey[2]):
            hall = cifdata[sgkey[2]]
            sgnum = sg.Hall_to_sgnum[HM]  

        # lattice parameters
        lparms = []
        lpkey = ['_cell_length_a', '_cell_length_b', \
                 '_cell_length_c', '_cell_angle_alpha', \
                 '_cell_angle_beta', '_cell_angle_gamma']   

        for key in lpkey:
            n = cifdata[key].find('(')
            if(n != -1):
                lparms.append(float(cifdata[key][:n]))
            else:
                lparms.append(float(cifdata[key]))

        for i in range(6):
                if(i < 3):
                    lparms[i] = _angstroms(lparms[i])
                else:
                    lparms[i] = _degrees(lparms[i])

        self._lparms = lparms
        self.sgnum   = sgnum

        # fractional atomic site, occ and vibration amplitude
        fracsitekey = ['_atom_site_fract_x', '_atom_site_fract_y',\
                        '_atom_site_fract_z',]

        occ_U       = ['_atom_site_occupancy',\
                        '_atom_site_u_iso_or_equiv','_atom_site_U_iso_or_equiv']

        sitedata = True
        for key in fracsitekey:
            sitedata = sitedata and (key in cifdata)

        if(not(sitedata)):
            raise RuntimeError(' fractional site position is not present or incomplete in the CIF file! ')

        atompos = []
        for key in fracsitekey:
            slist = cifdata[key]
            pos = []

            for p in slist:
                n = p.find('(')

                if(n != -1):
                    pos.append(p[:n])
                else:
                    pos.append(p)

            '''
            sometimes cif files have negative values so need to 
            bring them back to fractional coordinates between 0-1
            '''
            pos = numpy.asarray(pos).astype(numpy.float64)
            pos,_ = numpy.modf(pos+100.0)
            atompos.append(pos)
        
        """note that the vibration amplitude, U is just the amplitude (in A)
            to convert to the typical B which occurs in the debye-waller factor,
            we will use the following formula
            B = 8 * pi ^2 * < U_av^2 >
            this will be done here so we dont have to worry about it later 
        """

        pocc = (occ_U[0] in cifdata.keys())
        pU   = (occ_U[1] in cifdata.keys()) or (occ_U[2] in cifdata.keys())

        if(not pocc):
            warn('occupation fraction not present. setting it to 1')
            occ = numpy.ones(atompos[0].shape)
            atompos.append(occ)
        else:
            slist = cifdata[occ_U[0]]
            occ = []
            for p in slist:
                n = p.find('(')

                if(n != -1):
                    occ.append(p[:n])
                else:
                    occ.append(p)

            atompos.append(numpy.asarray(occ).astype(numpy.float64))

        if(not pU):
            warn('Debye-Waller factors not present. setting to same values for all atoms.')
            U = 1.0/numpy.pi/2./numpy.sqrt(2.) * numpy.ones(atompos[0].shape)
            atompos.append(U)
        else:
            if(occ_U[1] in cifdata.keys()):
                k = occ_U[1]
            else:
                k = occ_U[2]

            slist = cifdata[k]
            U = []
            for p in slist:
                n = p.find('(')

                if(n != -1):
                    U.append(p[:n])
                else:
                    U.append(p)

            atompos.append(numpy.asarray(U).astype(numpy.float64))

        '''
        format everything in the right shape etc.
        '''
        self._atominfo = numpy.asarray(atompos).T
        self._atominfo[:,4] = 8.0 * (numpy.pi**2) * (self._atominfo[:,4]**2) * 1E-2

        '''
        get atome types here i.e. the atomic number of atoms at each site
        '''
        atype = '_atom_site_type_symbol'
        patype = (atype in cifdata)
        if(not patype):
            raise RuntimeError('atom types not defined in cif file.')

        satype = cifdata[atype]
        atomtype = []

        for s in satype:
            atomtype.append(ptable[s])

        self._atomtype  = numpy.asarray(atomtype).astype(numpy.int32)
        self._sgsetting = 0

    def _readHDFxtal(self, fhdf=DFLT_NAME, xtal=DFLT_NAME):
        """
        >> @AUTHOR:     Saransh Singh, Lawrence Livermore National Lab, [email protected]
        >> @DATE:       10/17/2019 SS 1.0 original
        >> @DETAILS:    hexrd3 will have real structure factors and will require the overhaul
                        of the crystallography. In this effort, we will have a HDF file reader.
                        the file will be the same as the EMsoft xtal file. h5py will be used for
                        i/o
        """

        fexist = path.exists(fhdf)
        if(fexist):
            fid = h5py.File(fhdf, 'r')
            xtal = "/"+xtal
            if xtal not in fid:
                raise IOError('crystal doesn''t exist in material file.')
        else:
            raise IOError('material file does not exist.')

        gid         = fid.get(xtal)
        
        sgnum       = numpy.asscalar(numpy.array(gid.get('SpaceGroupNumber'), \
                                    dtype = numpy.int32))
        """ 
            IMPORTANT NOTE:
            note that the latice parameters in EMsoft is nm by default
            hexrd on the other hand uses A as the default units, so we
            need to be careful and convert it right here, so there is no
            confusion later on
        """
        lparms      = list(gid.get('LatticeParameters'))

        for i in range(6):
            if(i < 3):
                lparms[i] = _angstroms(lparms[i]*10.0)
            else:
                lparms[i] = _degrees(lparms[i])

        self._lparms    = lparms
        #self._lparms    = self._toSixLP(sgnum, lparms)
        # fill space group and lattice parameters
        self.sgnum      = sgnum

        # the U factors are related to B by the relation B = 8pi^2 U
        self._atominfo  = numpy.transpose(numpy.array(gid.get('AtomData'), dtype = numpy.float64))
        self._U         = numpy.transpose(numpy.array(gid.get('U'), dtype = numpy.float64))

        # read atom types (by atomic number, Z)
        self._atomtype = numpy.array(gid.get('Atomtypes'), dtype = numpy.int32)
        self._atom_ntype = self._atomtype.shape[0]
        
        self._sgsetting = numpy.asscalar(numpy.array(gid.get('SpaceGroupSetting'), \
                                        dtype = numpy.int32))
        self._sgsetting -= 1

        fid.close()

    # ============================== API
    #
    #  ========== Properties
    #

    # property:  spaceGroup

    @property
    def spaceGroup(self):
        """(read only) Space group"""
        return self._spaceGroup

    @property
    def vol(self):
        return self.unitcell.vol
    

    # property:  sgnum

    def _get_sgnum(self):
        """Get method for sgnum"""
        return self._sgnum

    def _set_sgnum(self, v):
        """Set method for sgnum"""
        self._sgnum = v
        self._spaceGroup = SG(self._sgnum)
        self._newPdata()

        return

    sgnum = property(_get_sgnum, _set_sgnum, None,
                     "Space group number")
    # property:  beamEnergy

    def _get_beamEnergy(self):
        """Get method for beamEnergy"""
        return self._beamEnergy

    def _set_beamEnergy(self, keV):
        """
        Set method for beamEnergy

        * note that units are assumed to be keV for
          float arguments.  Also can take a valWUnit
          instance
        """
        self._beamEnergy = keV
        self.planeData.wavelength = keV

        return

    beamEnergy = property(_get_beamEnergy, _set_beamEnergy, None,
                          "Beam energy in keV")

    # property:  hklMax

    def _get_hklMax(self):
        """Get method for hklMax"""
        return self._hklMax

    def _set_hklMax(self, v):
        """Set method for hklMax"""
        self._hklMax = v
        self._newPdata()  # update planeData
        return

    hklMax = property(_get_hklMax, _set_hklMax, None,
                      "Max sum of squares for HKLs")
    # property:  planeData

    @property
    def planeData(self):
        """(read only) Return the planeData attribute (lattice parameters)"""
        return self._pData

    # property:  latticeParameters

    def _get_latticeParameters(self):
        """Get method for latticeParameters"""
        return self._lparms

    def _set_latticeParameters(self, v):
        """Set method for latticeParameters"""
        self._lparms = self._toSixLP(self.sgnum, v)
        # self._newPdata()
        self.planeData.lparms = v

        return

    lpdoc = r"""Lattice parameters

On output, all six paramters are returned.

On input, either all six or a minimal set is accepted.

The values have units attached, i.e. they are valWunit instances.
"""
    latticeParameters = property(
            _get_latticeParameters, _set_latticeParameters,
            None, lpdoc)

    # property:  "name"

    def _get_name(self):
        """Set method for name"""
        return self._name

    def _set_name(self, v):
        """Set method for name"""
        self._name = v

        return

    name = property(_get_name, _set_name, None,
                    "Name of material")

    # property: "atominfo"
    def _get_atominfo(self):
        """Set method for name"""
        return self._atominfo

    def _set_atominfo(self, v):
        """Set method for name"""
        if v.shape[1] == 4:
            self._atominfo = v
        else:
            print("Improper syntax, array must be n x 4")

        return

    atominfo = property(
        _get_atominfo, _set_atominfo, None,
        "Information about atomic positions and electron number")

    #
    #  ========== Methods
    #
    #
    pass  # end class
예제 #25
0
    np.zeros(3))
pixel_tth = gcrds[0][0]

detector_params = np.hstack(
    [tiltAngles, tVec_d.flatten(), chi,
     tVec_s.flatten()])

distortion = None

#==============================================================================
# %% crystallography data
#==============================================================================
gold = make_matl('gold', 225, [
    4.0782,
], hkl_ssq_max=200)
gold.beamEnergy = valunits.valWUnit("wavelength", "ENERGY", 52, "keV")
pd = gold.planeData
pd.exclusions = np.zeros(len(pd.exclusions), dtype=bool)
pd.tThMax = np.amax(pixel_tth)


#==============================================================================
# %% DIFFRACTION SIMULATION
#==============================================================================
def simulate_diffractions(grain_params):
    pbar = ProgressBar(widgets=['simulate_diffractions',
                                Percentage(),
                                Bar()],
                       maxval=len(grain_params)).start()

    image_stack = np.zeros((nframes, nrows, ncols), dtype=bool)
예제 #26
0
class Material(object):
    """Simple class for holding lattice parameters, accessible by name.

    The class references materials by name and contains lattice and
    space group data.
    """
    DFLT_NAME = 'material'
    DFLT_SGNUM = 230
    DFLT_LPARMS = [
        _angstroms(1.0),
        _angstroms(1.0),
        _angstroms(1.0),
        _degrees(90.0),
        _degrees(90.0),
        _degrees(90.0)
    ]
    DFLT_SSMAX = 50

    DFLT_KEV = valWUnit('wavelength', 'energy', 80.725e0, 'keV')
    DFLT_STR = 0.0025
    DFLT_TTH = numpy.radians(0.25)
    DFLT_ATOMINFO = numpy.array([[0, 0, 0, 1]])
    """Fractional Atom Position of an atom in the unit cell followed by the
    number of electrons within that atom. The max number of electrons is 96.
    """
    def __init__(self, name=DFLT_NAME, cfgP=None):
        """Constructor for Material

        name -- (str) name of material
        cfgP -- (instance) configuration file parser with
             -- the material name as a section
        """
        self.name = name
        self.description = ''
        if cfgP:
            # Get values from configuration
            self._readCfg(cfgP)
            pass
        else:
            # Use default values
            self._lparms = Material.DFLT_LPARMS
            self._hklMax = Material.DFLT_SSMAX
            #
            self._beamEnergy = Material.DFLT_KEV
            #
            self.description = ''
            #
            self.sgnum = Material.DFLT_SGNUM
            #
            self._atominfo = Material.DFLT_ATOMINFO
            #
            pass
        return

    def __str__(self):
        """String representation"""
        s = 'Material:  %s\n' % self.name
        if self.description:
            s += '   description:  %s\n' % self.description
            pass
        s += '   plane Data:  %s' % str(self.planeData)
        return s

    def _readCfg(self, p):
        """Read values from config parser"""

        # Lattice parameters

        lpStrings = (('a-in-angstroms', _angstroms), ('b-in-angstroms',
                                                      _angstroms),
                     ('c-in-angstroms', _angstroms), ('alpha-in-degrees',
                                                      _degrees),
                     ('beta-in-degrees', _degrees), ('gamma-in-degrees',
                                                     _degrees))

        sgnum = p.getint(self.name, 'space-group')
        tmpSG = SG(sgnum)

        try:
            hklMax = p.getint(self.name, 'hkls-ssmax')
        except:
            hklMax = Material.DFLT_SSMAX

        try:
            beamEnergy = p.getfloat(self.name, 'beam-energy')
        except:
            beamEnergy = Material.DFLT_KEV

        lparams = []
        for ind in tmpSG.reqParams:
            param, unit = lpStrings[ind]
            lparams.append(unit(p.getfloat(self.name, param)))
            pass

        # Initialize
        self._hklMax = hklMax
        self._beamEnergy = beamEnergy
        self._lparms = self._toSixLP(sgnum, lparams)
        self.sgnum = sgnum
        self.description = p.get(self.name, 'description')

        return

    def _newPdata(self):
        """Create a new plane data instance"""
        # spaceGroup module calculates forbidden reflections
        hkls = numpy.array(self.spaceGroup.getHKLs(self.hklMax)).T
        lprm = [self._lparms[i] for i in self.spaceGroup.reqParams]
        laue = self.spaceGroup.laueGroup
        self._pData = PData(hkls,
                            lprm,
                            laue,
                            self._beamEnergy,
                            Material.DFLT_STR,
                            tThWidth=Material.DFLT_TTH)
        #
        #  Set default exclusions
        #
        dflt_excl = numpy.array(
            [1 for i in range(len(self._pData.exclusions))], dtype=bool)
        dflt_excl[:5] = False
        self._pData.exclusions = dflt_excl

        return

    def _toSixLP(self, sgn, lp):
        """
        Generate all six lattice parameters, making sure units are attached.
        """
        tmpSG = SG(sgn)
        lp6 = list(tmpSG.sixLatticeParams(lp))

        # make sure angles have attached units
        for i in range(6):
            if not hasattr(lp6[i], 'getVal'):
                if i in range(3):
                    lp6[i] = _angstroms(lp6[i])
                else:
                    lp6[i] = _degrees(lp6[i])
                    pass
                pass
            pass

        return lp6

    #
    # ============================== API
    #
    #  ========== Properties
    #

    # property:  spaceGroup

    @property
    def spaceGroup(self):
        """(read only) Space group"""
        return self._spaceGroup

    # property:  sgnum

    def _get_sgnum(self):
        """Get method for sgnum"""
        return self._sgnum

    def _set_sgnum(self, v):
        """Set method for sgnum"""
        self._sgnum = v
        self._spaceGroup = SG(self._sgnum)
        self._newPdata()

        return

    sgnum = property(_get_sgnum, _set_sgnum, None, "Space group number")

    # property:  beamEnergy

    def _get_beamEnergy(self):
        """Get method for beamEnergy"""
        return self._beamEnergy

    def _set_beamEnergy(self, keV):
        """
        Set method for beamEnergy

        * note that units are assumed to be keV for
          float arguments.  Also can take a valWUnit
          instance
        """
        self._beamEnergy = keV
        self.planeData.wavelength = keV

        return

    beamEnergy = property(_get_beamEnergy, _set_beamEnergy, None,
                          "Beam energy in keV")

    # property:  hklMax

    def _get_hklMax(self):
        """Get method for hklMax"""
        return self._hklMax

    def _set_hklMax(self, v):
        """Set method for hklMax"""
        self._hklMax = v
        self._newPdata()  # update planeData
        return

    hklMax = property(_get_hklMax, _set_hklMax, None,
                      "Max sum of squares for HKLs")
    # property:  planeData

    @property
    def planeData(self):
        """(read only) Return the planeData attribute (lattice parameters)"""
        return self._pData

    # property:  latticeParameters

    def _get_latticeParameters(self):
        """Get method for latticeParameters"""
        return self._lparms

    def _set_latticeParameters(self, v):
        """Set method for latticeParameters"""
        self._lparms = self._toSixLP(self.sgnum, v)
        # self._newPdata()
        self.planeData.lparms = v

        return

    lpdoc = r"""Lattice parameters

On output, all six paramters are returned.

On input, either all six or a minimal set is accepted.

The values have units attached, i.e. they are valWunit instances.
"""
    latticeParameters = property(_get_latticeParameters,
                                 _set_latticeParameters, None, lpdoc)

    # property:  "name"

    def _get_name(self):
        """Set method for name"""
        return self._name

    def _set_name(self, v):
        """Set method for name"""
        self._name = v

        return

    name = property(_get_name, _set_name, None, "Name of material")

    # property: "atominfo"
    def _get_atominfo(self):
        """Set method for name"""
        return self._atominfo

    def _set_atominfo(self, v):
        """Set method for name"""
        if v.shape[1] == 4:
            self._atominfo = v
        else:
            print("Improper syntax, array must be n x 4")

        return

    atominfo = property(
        _get_atominfo, _set_atominfo, None,
        "Information about atomic positions and electron number")

    #
    #  ========== Methods
    #
    #
    pass  # end class
예제 #27
0
파일: nfutil.py 프로젝트: rachelelim/hexrd
def gen_trial_exp_data(grain_out_file,det_file,mat_file, x_ray_energy, mat_name, max_tth, comp_thresh, chi2_thresh, misorientation_bnd, \
                       misorientation_spacing,ome_range_deg, nframes, beam_stop_width):

    print('Loading Grain Data.....')
    #gen_grain_data
    ff_data = np.loadtxt(grain_out_file)

    #ff_data=np.atleast_2d(ff_data[2,:])

    exp_maps = ff_data[:, 3:6]
    t_vec_ds = ff_data[:, 6:9]

    #
    completeness = ff_data[:, 1]

    chi2 = ff_data[:, 2]

    n_grains = exp_maps.shape[0]

    rMat_c = rot.rotMatOfExpMap(exp_maps.T)

    cut = np.where(
        np.logical_and(completeness > comp_thresh, chi2 < chi2_thresh))[0]
    exp_maps = exp_maps[cut, :]
    t_vec_ds = t_vec_ds[cut, :]
    chi2 = chi2[cut]

    # Add Misorientation
    mis_amt = misorientation_bnd * np.pi / 180.
    spacing = misorientation_spacing * np.pi / 180.

    mis_steps = int(misorientation_bnd / misorientation_spacing)

    ori_pts = np.arange(-mis_amt, (mis_amt + (spacing * 0.999)), spacing)
    num_ori_grid_pts = ori_pts.shape[0]**3
    num_oris = exp_maps.shape[0]

    XsO, YsO, ZsO = np.meshgrid(ori_pts, ori_pts, ori_pts)

    grid0 = np.vstack([XsO.flatten(), YsO.flatten(), ZsO.flatten()]).T

    exp_maps_expanded = np.zeros([num_ori_grid_pts * num_oris, 3])
    t_vec_ds_expanded = np.zeros([num_ori_grid_pts * num_oris, 3])

    for ii in np.arange(num_oris):
        pts_to_use = np.arange(num_ori_grid_pts) + ii * num_ori_grid_pts
        exp_maps_expanded[pts_to_use, :] = grid0 + np.r_[exp_maps[ii, :]]
        t_vec_ds_expanded[pts_to_use, :] = np.r_[t_vec_ds[ii, :]]

    exp_maps = exp_maps_expanded
    t_vec_ds = t_vec_ds_expanded

    n_grains = exp_maps.shape[0]

    rMat_c = rot.rotMatOfExpMap(exp_maps.T)

    print('Loading Instrument Data.....')
    instr_cfg = yaml.load(open(det_file, 'r'))

    tiltAngles = instr_cfg['detector']['transform']['tilt_angles']
    tVec_d = np.array(instr_cfg['detector']['transform']['t_vec_d']).reshape(
        3, 1)
    #tVec_d[0] = -0.05
    chi = instr_cfg['oscillation_stage']['chi']
    tVec_s = np.array(instr_cfg['oscillation_stage']['t_vec_s']).reshape(3, 1)

    rMat_d = makeDetectorRotMat(tiltAngles)
    rMat_s = makeOscillRotMat([chi, 0.])

    pixel_size = instr_cfg['detector']['pixels']['size']

    nrows = instr_cfg['detector']['pixels']['rows']
    ncols = instr_cfg['detector']['pixels']['columns']

    #    row_dim = pixel_size[0]*nrows # in mm
    #    col_dim = pixel_size[1]*ncols # in mm

    x_col_edges = pixel_size[1] * (np.arange(ncols + 1) - 0.5 * ncols)
    y_row_edges = pixel_size[0] * (np.arange(nrows + 1) - 0.5 * nrows)[::-1]

    panel_dims = [(-0.5 * ncols * pixel_size[1], -0.5 * nrows * pixel_size[0]),
                  (0.5 * ncols * pixel_size[1], 0.5 * nrows * pixel_size[0])]

    # a bit overkill, but grab max two-theta from all pixel transforms
    rx, ry = np.meshgrid(x_col_edges, y_row_edges)
    gcrds = detectorXYToGvec(
        np.vstack([rx.flatten(), ry.flatten()]).T, rMat_d, rMat_s, tVec_d,
        tVec_s, np.zeros(3))
    pixel_tth = gcrds[0][0]

    detector_params = np.hstack(
        [tiltAngles, tVec_d.flatten(), chi,
         tVec_s.flatten()])

    ome_period_deg = (ome_range_deg[0][0], (ome_range_deg[0][0] + 360.)
                      )  #degrees
    ome_step_deg = (ome_range_deg[0][1] -
                    ome_range_deg[0][0]) / nframes  #degrees

    ome_period = (ome_period_deg[0] * np.pi / 180.,
                  ome_period_deg[1] * np.pi / 180.)
    ome_range = [(ome_range_deg[0][0] * np.pi / 180.,
                  ome_range_deg[0][1] * np.pi / 180.)]
    ome_step = ome_step_deg * np.pi / 180.

    ome_edges = np.arange(nframes +
                          1) * ome_step + ome_range[0][0]  #fixed 2/26/17

    base = np.array([x_col_edges[0], y_row_edges[0], ome_edges[0]])
    deltas = np.array([
        x_col_edges[1] - x_col_edges[0], y_row_edges[1] - y_row_edges[0],
        ome_edges[1] - ome_edges[0]
    ])
    inv_deltas = 1.0 / deltas
    clip_vals = np.array([ncols, nrows])

    print('Loading Material Data.....')
    #Load Material Data
    materials = cpl.load(open(mat_file, "rb"))

    check = np.zeros(len(materials))
    for ii in np.arange(len(materials)):
        #print materials[ii].name
        check[ii] = materials[ii].name == mat_name

    mat_used = materials[np.where(check)[0][0]]

    #niti_mart.beamEnergy = valunits.valWUnit("wavelength","ENERGY",61.332,"keV")
    mat_used.beamEnergy = valunits.valWUnit("wavelength", "ENERGY",
                                            x_ray_energy, "keV")
    mat_used.planeData.exclusions = np.zeros(len(
        mat_used.planeData.exclusions),
                                             dtype=bool)

    if max_tth > 0.:
        mat_used.planeData.tThMax = np.amax(np.radians(max_tth))
    else:
        mat_used.planeData.tThMax = np.amax(pixel_tth)

    pd = mat_used.planeData

    print('Final Assembly.....')
    experiment = argparse.Namespace()
    # grains related information
    experiment.n_grains = n_grains  # this can be derived from other values...
    experiment.rMat_c = rMat_c  # n_grains rotation matrices (one per grain)
    experiment.exp_maps = exp_maps  # n_grains exp_maps -angle * rotation axis- (one per grain)

    experiment.plane_data = pd
    experiment.detector_params = detector_params
    experiment.pixel_size = pixel_size
    experiment.ome_range = ome_range
    experiment.ome_period = ome_period
    experiment.x_col_edges = x_col_edges
    experiment.y_row_edges = y_row_edges
    experiment.ome_edges = ome_edges
    experiment.ncols = ncols
    experiment.nrows = nrows
    experiment.nframes = nframes  # used only in simulate...
    experiment.rMat_d = rMat_d
    experiment.tVec_d = np.atleast_2d(detector_params[3:6]).T
    experiment.chi = detector_params[
        6]  # note this is used to compute S... why is it needed?
    experiment.tVec_s = np.atleast_2d(detector_params[7:]).T
    experiment.rMat_c = rMat_c
    experiment.distortion = None
    experiment.panel_dims = panel_dims  # used only in simulate...
    experiment.base = base
    experiment.inv_deltas = inv_deltas
    experiment.clip_vals = clip_vals
    experiment.bsw = beam_stop_width

    if mis_steps == 0:
        nf_to_ff_id_map = cut
    else:
        nf_to_ff_id_map = np.tile(cut, 27 * mis_steps)

    return experiment, nf_to_ff_id_map
예제 #28
0
         pwA = plotwrap.PlotWrap()
         pwA(predAngles[:,0],    predAngles[:,1],    style='r+')
         pwA(foundSpotAngs[:,0], foundSpotAngs[:,1], style='gx')
         # alignment is good, but definitely missing somex
         pwB = plotwrap.PlotWrap()
         pwB(predAngles[:,0],    predAngles[:,2],    style='r+')
         pwB(foundSpotAngs[:,0], foundSpotAngs[:,2], style='gx')
         '''
 
     
     nSpotsTThAll, nSpotsTThClaimed, numClaimed, numMultiClaimed = spotsForFit.report(scaleByMultip=False)
     # iHKL = num.argmax(nSpotsTThAll)
     iHKL = num.where(nSpotsTThAll == num.unique(nSpotsTThAll)[1])[0][0]
     hklListForIndex = [ tuple(planeData.getHKLs()[iHKL]), ]
     
     etaTol = valunits.valWUnit('etaTol', 'angle', 0.5, 'degrees')
     omeTol = valunits.valWUnit('omeTol', 'angle', 0.5, 'degrees')
     rMat = indexer.fiberSearch(spotsForFit, 
                                hklListForIndex,
                                iPhase=planeData.phaseID,
                                nsteps=720,
                                minCompleteness=0.70,
                                minPctClaimed=0.75,
                                friedelOnly=False,
                                dspTol=None,
                                etaTol=etaTol,
                                omeTol=omeTol,
                                debug=True,
                                doMultiProc=opts.doMultiProc,
                                doRefinement=False)
     print 'found %d grains' % (rMat.shape[0])
예제 #29
0
def mockup_experiment():
    # user options
    # each grain is provided in the form of a quaternion.

    # The following array contains the quaternions for the array. Note that the
    # quaternions are in the columns, with the first row (row 0) being the real
    # part w. We assume that we are dealing with unit quaternions

    quats = np.array([[0.91836393, 0.90869942], [0.33952917, 0.1834835],
                      [0.17216207, 0.10095837], [0.10811041, 0.36111851]])

    n_grains = quats.shape[-1]  # last dimension provides the number of grains
    phis = 2. * np.arccos(
        quats[0, :])  # phis are the angles for the quaternion
    ns = mutil.unitVector(
        quats[1:, :])  # ns contains the rotation axis as an unit vector
    exp_maps = np.array([phis[i] * ns[:, i] for i in range(n_grains)])
    rMat_c = rot.rotMatOfQuat(quats)

    cvec = np.arange(-25, 26)
    X, Y, Z = np.meshgrid(cvec, cvec, cvec)

    crd0 = 1e-3 * np.vstack([X.flatten(), Y.flatten(), Z.flatten()]).T
    crd1 = crd0 + np.r_[0.100, 0.100, 0]
    crds = np.array([crd0, crd1])

    # make grain parameters
    grain_params = []
    for i in range(n_grains):
        for j in range(len(crd0)):
            grain_params.append(
                np.hstack(
                    [exp_maps[i, :], crds[i][j, :],
                     xf.vInv_ref.flatten()]))

    # scan range and period
    ome_period = (0, 2 * np.pi)
    ome_range = [
        ome_period,
    ]
    ome_step = np.radians(1.)
    nframes = 0
    for i in range(len(ome_range)):
        del_ome = ome_range[i][1] - ome_range[i][0]
        nframes += int((ome_range[i][1] - ome_range[i][0]) / ome_step)

    ome_edges = np.arange(nframes + 1) * ome_step

    # instrument
    with open('./retiga.yml', 'r') as fildes:
        instr_cfg = yaml.load(fildes)

    tiltAngles = instr_cfg['detector']['transform']['tilt_angles']
    tVec_d = np.array(instr_cfg['detector']['transform']['t_vec_d']).reshape(
        3, 1)
    chi = instr_cfg['oscillation_stage']['chi']
    tVec_s = np.array(instr_cfg['oscillation_stage']['t_vec_s']).reshape(3, 1)
    rMat_d = xfcapi.makeDetectorRotMat(tiltAngles)
    rMat_s = xfcapi.makeOscillRotMat([chi, 0.])

    pixel_size = instr_cfg['detector']['pixels']['size']
    nrows = instr_cfg['detector']['pixels']['rows']
    ncols = instr_cfg['detector']['pixels']['columns']

    col_ps = pixel_size[1]
    row_ps = pixel_size[0]

    row_dim = row_ps * nrows  # in mm
    col_dim = col_ps * ncols  # in mm
    panel_dims = [(-0.5 * ncols * col_ps, -0.5 * nrows * row_ps),
                  (0.5 * ncols * col_ps, 0.5 * nrows * row_ps)]

    x_col_edges = col_ps * (np.arange(ncols + 1) - 0.5 * ncols)
    y_row_edges = row_ps * (np.arange(nrows, -1, -1) - 0.5 * nrows)
    #x_col_edges = np.arange(panel_dims[0][0], panel_dims[1][0] + 0.5*col_ps, col_ps)
    #y_row_edges = np.arange(panel_dims[0][1], panel_dims[1][1] + 0.5*row_ps, row_ps)
    rx, ry = np.meshgrid(x_col_edges, y_row_edges)

    gcrds = xfcapi.detectorXYToGvec(
        np.vstack([rx.flatten(), ry.flatten()]).T, rMat_d, rMat_s, tVec_d,
        tVec_s, np.zeros(3))

    max_pixel_tth = np.amax(gcrds[0][0])
    detector_params = np.hstack(
        [tiltAngles, tVec_d.flatten(), chi,
         tVec_s.flatten()])
    distortion = None

    # a different parametrization for the sensor (makes for faster quantization)
    base = np.array([x_col_edges[0], y_row_edges[0], ome_edges[0]])
    deltas = np.array([
        x_col_edges[1] - x_col_edges[0], y_row_edges[1] - y_row_edges[0],
        ome_edges[1] - ome_edges[0]
    ])
    inv_deltas = 1.0 / deltas
    clip_vals = np.array([ncols, nrows])

    # dilation
    max_diameter = np.sqrt(3) * 0.005
    row_dilation = np.ceil(0.5 * max_diameter / row_ps)
    col_dilation = np.ceil(0.5 * max_diameter / col_ps)

    # crystallography data
    from hexrd import valunits
    gold = material.Material('gold')
    gold.sgnum = 225
    gold.latticeParameters = [
        4.0782,
    ]
    gold.hklMax = 200
    gold.beamEnergy = valunits.valWUnit("wavelength", "ENERGY", 52, "keV")
    gold.planeData.exclusions = None
    gold.planeData.tThMax = max_pixel_tth  #note this comes from info in the detector

    ns = argparse.Namespace()
    # grains related information
    ns.n_grains = n_grains  # this can be derived from other values...
    ns.rMat_c = rMat_c  # n_grains rotation matrices (one per grain)
    ns.exp_maps = exp_maps  # n_grains exp_maps -angle * rotation axis- (one per grain)

    ns.plane_data = gold.planeData
    ns.detector_params = detector_params
    ns.pixel_size = pixel_size
    ns.ome_range = ome_range
    ns.ome_period = ome_period
    ns.x_col_edges = x_col_edges
    ns.y_row_edges = y_row_edges
    ns.ome_edges = ome_edges
    ns.ncols = ncols
    ns.nrows = nrows
    ns.nframes = nframes  # used only in simulate...
    ns.rMat_d = rMat_d
    ns.tVec_d = tVec_d
    ns.chi = chi  # note this is used to compute S... why is it needed?
    ns.tVec_s = tVec_s
    # ns.rMat_s = rMat_s
    # ns.tVec_s = tVec_s
    ns.rMat_c = rMat_c
    ns.row_dilation = row_dilation
    ns.col_dilation = col_dilation
    ns.distortion = distortion
    ns.panel_dims = panel_dims  # used only in simulate...
    ns.base = base
    ns.inv_deltas = inv_deltas
    ns.clip_vals = clip_vals

    return grain_params, ns
예제 #30
0
# a bit overkill, but grab max two-theta from all pixel transforms
rx, ry = np.meshgrid(x_col_edges, y_row_edges)
gcrds = detectorXYToGvec(np.vstack([rx.flatten(), ry.flatten()]).T,
                         rMat_d, rMat_s,
                         tVec_d, tVec_s, np.zeros(3))
pixel_tth = gcrds[0][0]

detector_params = np.hstack([tiltAngles, tVec_d.flatten(), chi, tVec_s.flatten()])

distortion = None

#==============================================================================
# %% crystallography data
#==============================================================================
gold = make_matl('gold', 225, [4.0782,], hkl_ssq_max=200)
gold.beamEnergy = valunits.valWUnit("wavelength","ENERGY",52,"keV")
pd = gold.planeData
pd.exclusions = np.zeros(len(pd.exclusions), dtype=bool)
pd.tThMax = np.amax(pixel_tth)

#==============================================================================
# %% DIFFRACTION SIMULATION
#==============================================================================
def simulate_diffractions(grain_params):
    pbar = ProgressBar(widgets=['simulate_diffractions', Percentage(), Bar()],
                       maxval=len(grain_params)).start()

    image_stack = np.zeros((nframes, nrows, ncols), dtype=bool)
    for i in range(len(grain_params)):
        sim_results = xrdutil.simulateGVecs(pd,
                                            detector_params,
예제 #31
0
from hexrd.xrd import detector
from hexrd.xrd import grain as G
from hexrd.xrd import indexer
from hexrd.xrd import rotations as ROT
from hexrd.xrd import spotfinder as SPT

from hexrd.xrd.hydra import Hydra
from hexrd.xrd.material import Material, loadMaterialList

from math import pi

numpy.seterr(invalid='ignore')
r2d = 180. / pi
d2r = pi / 180.
OMEGA_PERIOD = (-pi, pi)
coarse_ang_tol = valunits.valWUnit('coarse tol', 'angle', 1.0, 'degrees')
fine_ang_tol = valunits.valWUnit('fine tol', 'angle', 0.5, 'degrees')

# =============================================================================
# Defaults (will eventually make to a config file)
# =============================================================================

HERE = os.path.dirname(__file__)
toMatFile = os.path.join(HERE, '..', 'data', 'materials.cfg')
DFLT_MATFILE = os.path.normpath(toMatFile)  # check whether it exists
matfileOK = os.access(DFLT_MATFILE, os.F_OK)
if not matfileOK:  # use relative path
    DFLT_MATFILE = os.path.join('data', 'materials.cfg')
    pass
matfileOK = os.access(DFLT_MATFILE, os.F_OK)
if not matfileOK:  # set to null
예제 #32
0
 def _kev(x):
     return valWUnit('beamenergy', 'energy', x, 'keV')
예제 #33
0
         pwA = plotwrap.PlotWrap()
         pwA(predAngles[:,0],    predAngles[:,1],    style='r+')
         pwA(foundSpotAngs[:,0], foundSpotAngs[:,1], style='gx')
         # alignment is good, but definitely missing somex
         pwB = plotwrap.PlotWrap()
         pwB(predAngles[:,0],    predAngles[:,2],    style='r+')
         pwB(foundSpotAngs[:,0], foundSpotAngs[:,2], style='gx')
         '''
 
     
     nSpotsTThAll, nSpotsTThClaimed, numClaimed, numMultiClaimed = spotsForFit.report(scaleByMultip=False)
     # iHKL = num.argmax(nSpotsTThAll)
     iHKL = num.where(nSpotsTThAll == num.unique(nSpotsTThAll)[1])[0][0]
     hklListForIndex = [ tuple(planeData.getHKLs()[iHKL]), ]
     
     etaTol = valunits.valWUnit('etaTol', 'angle', 0.5, 'degrees')
     omeTol = valunits.valWUnit('omeTol', 'angle', 0.5, 'degrees')
     rMat = indexer.fiberSearch(spotsForFit, 
                                hklListForIndex,
                                iPhase=planeData.phaseID,
                                nsteps=720,
                                minCompleteness=0.70,
                                minPctClaimed=0.75,
                                friedelOnly=False,
                                dspTol=None,
                                etaTol=etaTol,
                                omeTol=omeTol,
                                debug=True,
                                doMultiProc=opts.doMultiProc,
                                doRefinement=False)
     print 'found %d grains' % (rMat.shape[0])
예제 #34
0
def _degrees(x):
    return valWUnit('lp', 'angle', x, 'degrees')
예제 #35
0
파일: nfutil.py 프로젝트: praxes/hexrd
def gen_trial_exp_data(grain_out_file,det_file,mat_file, x_ray_energy, mat_name, max_tth, comp_thresh, chi2_thresh, misorientation_bnd, \
                       misorientation_spacing,ome_range_deg, nframes, beam_stop_width):

    print('Loading Grain Data.....')
    #gen_grain_data
    ff_data=np.loadtxt(grain_out_file)
    
    #ff_data=np.atleast_2d(ff_data[2,:])
    
    exp_maps=ff_data[:,3:6]
    t_vec_ds=ff_data[:,6:9]
    
    
    # 
    completeness=ff_data[:,1]
    
    chi2=ff_data[:,2]
    
    n_grains=exp_maps.shape[0]
    
    rMat_c = rot.rotMatOfExpMap(exp_maps.T)
    
    
    
    
    cut=np.where(np.logical_and(completeness>comp_thresh,chi2<chi2_thresh))[0]
    exp_maps=exp_maps[cut,:]
    t_vec_ds=t_vec_ds[cut,:]
    chi2=chi2[cut]
  
    
    # Add Misorientation
    mis_amt=misorientation_bnd*np.pi/180.
    spacing=misorientation_spacing*np.pi/180.
    
    ori_pts = np.arange(-mis_amt, (mis_amt+(spacing*0.999)),spacing)
    num_ori_grid_pts=ori_pts.shape[0]**3
    num_oris=exp_maps.shape[0]
    
    
    XsO, YsO, ZsO = np.meshgrid(ori_pts, ori_pts, ori_pts)
    
    grid0 = np.vstack([XsO.flatten(), YsO.flatten(), ZsO.flatten()]).T
    
    
    exp_maps_expanded=np.zeros([num_ori_grid_pts*num_oris,3])
    t_vec_ds_expanded=np.zeros([num_ori_grid_pts*num_oris,3])
    
    
    for ii in np.arange(num_oris):
        pts_to_use=np.arange(num_ori_grid_pts)+ii*num_ori_grid_pts  
        exp_maps_expanded[pts_to_use,:]=grid0+np.r_[exp_maps[ii,:] ]
        t_vec_ds_expanded[pts_to_use,:]=np.r_[t_vec_ds[ii,:] ]      
    
    
    exp_maps=exp_maps_expanded
    t_vec_ds=t_vec_ds_expanded
    
    n_grains=exp_maps.shape[0]
    
    rMat_c = rot.rotMatOfExpMap(exp_maps.T)
    

    print('Loading Instrument Data.....')
    instr_cfg = yaml.load(open(det_file, 'r'))
    
    tiltAngles = instr_cfg['detector']['transform']['tilt_angles']
    tVec_d = np.array(instr_cfg['detector']['transform']['t_vec_d']).reshape(3, 1)
    #tVec_d[0] = -0.05
    chi = instr_cfg['oscillation_stage']['chi']
    tVec_s = np.array(instr_cfg['oscillation_stage']['t_vec_s']).reshape(3, 1)
    
    rMat_d = makeDetectorRotMat(tiltAngles)
    rMat_s = makeOscillRotMat([chi, 0.])
    
    pixel_size = instr_cfg['detector']['pixels']['size']
    
    nrows = instr_cfg['detector']['pixels']['rows']
    ncols = instr_cfg['detector']['pixels']['columns']
    
#    row_dim = pixel_size[0]*nrows # in mm 
#    col_dim = pixel_size[1]*ncols # in mm 
    
    x_col_edges = pixel_size[1]*(np.arange(ncols+1) - 0.5*ncols)
    y_row_edges = pixel_size[0]*(np.arange(nrows+1) - 0.5*nrows)[::-1]
    
    panel_dims = [(-0.5*ncols*pixel_size[1],
                   -0.5*nrows*pixel_size[0]),
                  ( 0.5*ncols*pixel_size[1],
                    0.5*nrows*pixel_size[0])]
    
    # a bit overkill, but grab max two-theta from all pixel transforms
    rx, ry = np.meshgrid(x_col_edges, y_row_edges)
    gcrds = detectorXYToGvec(np.vstack([rx.flatten(), ry.flatten()]).T,
                             rMat_d, rMat_s,
                             tVec_d, tVec_s, np.zeros(3))
    pixel_tth = gcrds[0][0]
    
    detector_params = np.hstack([tiltAngles, tVec_d.flatten(), chi, tVec_s.flatten()])

    
    ome_period_deg=(ome_range_deg[0][0], (ome_range_deg[0][0]+360.)) #degrees 
    ome_step_deg=(ome_range_deg[0][1]-ome_range_deg[0][0])/nframes #degrees 
    
    
    ome_period = (ome_period_deg[0]*np.pi/180.,ome_period_deg[1]*np.pi/180.)
    ome_range = [(ome_range_deg[0][0]*np.pi/180.,ome_range_deg[0][1]*np.pi/180.)]
    ome_step = ome_step_deg*np.pi/180.


    
    ome_edges = np.arange(nframes+1)*ome_step+ome_range[0][0]#fixed 2/26/17
    
    
    base = np.array([x_col_edges[0],
                     y_row_edges[0],
                     ome_edges[0]])
    deltas = np.array([x_col_edges[1] - x_col_edges[0],
                       y_row_edges[1] - y_row_edges[0],
                       ome_edges[1] - ome_edges[0]])
    inv_deltas = 1.0/deltas
    clip_vals = np.array([ncols, nrows])

    print('Loading Material Data.....')
    #Load Material Data
    materials=cpl.load(open( mat_file, "rb" ))


    check=np.zeros(len(materials))
    for ii in np.arange(len(materials)):
        #print materials[ii].name
        check[ii]=materials[ii].name==mat_name
    
    mat_used=materials[np.where(check)[0][0]]
    
    #niti_mart.beamEnergy = valunits.valWUnit("wavelength","ENERGY",61.332,"keV")
    mat_used.beamEnergy = valunits.valWUnit("wavelength","ENERGY",x_ray_energy,"keV")            
    mat_used.planeData.exclusions = np.zeros(len(mat_used.planeData.exclusions), dtype=bool)
    
    
    if max_tth>0.:
         mat_used.planeData.tThMax = np.amax(np.radians(max_tth))   
    else:
        mat_used.planeData.tThMax = np.amax(pixel_tth)        
    
    pd=mat_used.planeData
    
    
    print('Final Assembly.....')
    experiment = argparse.Namespace()
    # grains related information
    experiment.n_grains = n_grains # this can be derived from other values...
    experiment.rMat_c = rMat_c # n_grains rotation matrices (one per grain)
    experiment.exp_maps = exp_maps # n_grains exp_maps -angle * rotation axis- (one per grain)
    
    experiment.plane_data = pd
    experiment.detector_params = detector_params
    experiment.pixel_size = pixel_size
    experiment.ome_range = ome_range
    experiment.ome_period = ome_period
    experiment.x_col_edges = x_col_edges
    experiment.y_row_edges = y_row_edges
    experiment.ome_edges = ome_edges
    experiment.ncols = ncols
    experiment.nrows = nrows
    experiment.nframes = nframes# used only in simulate...
    experiment.rMat_d = rMat_d
    experiment.tVec_d = np.atleast_2d(detector_params[3:6]).T
    experiment.chi = detector_params[6] # note this is used to compute S... why is it needed?
    experiment.tVec_s = np.atleast_2d(detector_params[7:]).T
    experiment.rMat_c = rMat_c
    experiment.distortion = None
    experiment.panel_dims = panel_dims # used only in simulate...
    experiment.base = base
    experiment.inv_deltas = inv_deltas
    experiment.clip_vals = clip_vals
    experiment.bsw = beam_stop_width  
    
    nf_to_ff_id_map=cut
    
    return experiment, nf_to_ff_id_map
예제 #36
0
파일: material.py 프로젝트: QiangF/hexrd
Use the Material class directly for new materials.  Known
materials are defined by name in materialDict.
"""
from ConfigParser import SafeConfigParser as Parser
import numpy

from hexrd.xrd.crystallography import PlaneData as PData
from hexrd.xrd.spacegroup      import SpaceGroup as SG

from hexrd.valunits   import valWUnit
#
__all__ = ['Material', 'loadMaterialList']
#
# ================================================== Module Data
#
angstroms = lambda x: valWUnit('lp', 'length',  x, 'angstrom')
degrees   = lambda x: valWUnit('lp', 'angle',   x, 'degrees')
#
# ---------------------------------------------------CLASS:  Material
#
class Material(object):
    """Simple class for holding lattice parameters, accessible by name.

The class references materials by name and contains lattice and
space group data.
"""
    DFLT_NAME   = 'material'
    DFLT_SGNUM  = 230
    DFLT_LPARMS = [angstroms(1.0), angstroms(1.0), angstroms(1.0),
                   degrees(90.0), degrees(90.0), degrees(90.0)]
    DFLT_SSMAX  = 50
예제 #37
0
def mockup_experiment():
    # user options
    # each grain is provided in the form of a quaternion.

    # The following array contains the quaternions for the array. Note that the
    # quaternions are in the columns, with the first row (row 0) being the real
    # part w. We assume that we are dealing with unit quaternions

    quats = np.array([[0.91836393, 0.90869942], [0.33952917, 0.18348350],
                      [0.17216207, 0.10095837], [0.10811041, 0.36111851]])

    n_grains = quats.shape[-1]  # last dimension provides the number of grains
    phis = 2. * np.arccos(
        quats[0, :])  # phis are the angles for the quaternion
    # ns contains the rotation axis as an unit vector
    ns = hexrd.matrixutil.unitVector(quats[1:, :])
    exp_maps = np.array([phis[i] * ns[:, i] for i in range(n_grains)])
    rMat_c = rotations.rotMatOfQuat(quats)

    cvec = np.arange(-25, 26)
    X, Y, Z = np.meshgrid(cvec, cvec, cvec)

    crd0 = 1e-3 * np.vstack([X.flatten(), Y.flatten(), Z.flatten()]).T
    crd1 = crd0 + np.r_[0.100, 0.100, 0]
    crds = np.array([crd0, crd1])

    # make grain parameters
    grain_params = []
    for i in range(n_grains):
        for j in range(len(crd0)):
            grain_params.append(
                np.hstack([exp_maps[i, :], crds[i][j, :], vInv_ref]))

    # scan range and period
    ome_period = (0, 2 * np.pi)
    ome_range = [
        ome_period,
    ]
    ome_step = np.radians(1.)
    nframes = 0
    for i in range(len(ome_range)):
        nframes += int((ome_range[i][1] - ome_range[i][0]) / ome_step)

    ome_edges = np.arange(nframes + 1) * ome_step

    # instrument
    with open('./retiga.yml', 'r') as fildes:
        instr = instrument.HEDMInstrument(yaml.safe_load(fildes))
    panel = next(iter(instr.detectors.values()))  # !!! there is only 1

    # tranform paramters
    #   Sample
    chi = instr.chi
    tVec_s = instr.tvec
    #   Detector
    rMat_d = panel.rmat
    tilt_angles_xyzp = np.asarray(rotations.angles_from_rmat_xyz(rMat_d))
    tVec_d = panel.tvec

    # pixels
    row_ps = panel.pixel_size_row
    col_ps = panel.pixel_size_col
    pixel_size = (row_ps, col_ps)
    nrows = panel.rows
    ncols = panel.cols

    # panel dimensions
    panel_dims = [tuple(panel.corner_ll), tuple(panel.corner_ur)]

    x_col_edges = panel.col_edge_vec
    y_row_edges = panel.row_edge_vec
    rx, ry = np.meshgrid(x_col_edges, y_row_edges)

    max_pixel_tth = instrument.max_tth(instr)

    detector_params = np.hstack([tilt_angles_xyzp, tVec_d, chi, tVec_s])
    distortion = panel.distortion  # !!! must be None for now

    # a different parametrization for the sensor
    # (makes for faster quantization)
    base = np.array([x_col_edges[0], y_row_edges[0], ome_edges[0]])
    deltas = np.array([
        x_col_edges[1] - x_col_edges[0], y_row_edges[1] - y_row_edges[0],
        ome_edges[1] - ome_edges[0]
    ])
    inv_deltas = 1.0 / deltas
    clip_vals = np.array([ncols, nrows])

    # dilation
    max_diameter = np.sqrt(3) * 0.005
    row_dilation = int(np.ceil(0.5 * max_diameter / row_ps))
    col_dilation = int(np.ceil(0.5 * max_diameter / col_ps))

    # crystallography data
    beam_energy = valunits.valWUnit("beam_energy", "energy", instr.beam_energy,
                                    "keV")
    beam_wavelength = constants.keVToAngstrom(beam_energy.getVal('keV'))
    dmin = valunits.valWUnit(
        "dmin", "length", 0.5 * beam_wavelength / np.sin(0.5 * max_pixel_tth),
        "angstrom")

    gold = material.Material()
    gold.latticeParameters = [4.0782]
    gold.dmin = dmin
    gold.beamEnergy = beam_energy
    gold.planeData.exclusions = None
    gold.planeData.tThMax = max_pixel_tth  # note this comes detector

    ns = argparse.Namespace()
    # grains related information
    ns.n_grains = n_grains  # this can be derived from other values...
    ns.rMat_c = rMat_c  # n_grains rotation matrices (one per grain)
    ns.exp_maps = exp_maps  # n_grains exp_maps (one per grain)

    ns.plane_data = gold.planeData
    ns.detector_params = detector_params
    ns.pixel_size = pixel_size
    ns.ome_range = ome_range
    ns.ome_period = ome_period
    ns.x_col_edges = x_col_edges
    ns.y_row_edges = y_row_edges
    ns.ome_edges = ome_edges
    ns.ncols = ncols
    ns.nrows = nrows
    ns.nframes = nframes  # used only in simulate...
    ns.rMat_d = rMat_d
    ns.tVec_d = tVec_d
    ns.chi = chi  # note this is used to compute S... why is it needed?
    ns.tVec_s = tVec_s
    ns.rMat_c = rMat_c
    ns.row_dilation = row_dilation
    ns.col_dilation = col_dilation
    ns.distortion = distortion
    ns.panel_dims = panel_dims  # used only in simulate...
    ns.base = base
    ns.inv_deltas = inv_deltas
    ns.clip_vals = clip_vals

    return grain_params, ns
예제 #38
0
from hexrd.xrd import detector
from hexrd.xrd import grain as G
from hexrd.xrd import indexer
from hexrd.xrd import rotations as ROT
from hexrd.xrd import spotfinder as SPT

from hexrd.xrd.hydra import Hydra
from hexrd.xrd.material import Material, loadMaterialList

from math import pi

numpy.seterr(invalid='ignore')
r2d = 180. / pi
d2r = pi / 180.
OMEGA_PERIOD = (-pi, pi)
coarse_ang_tol = valunits.valWUnit('coarse tol', 'angle', 1.0, 'degrees')
fine_ang_tol = valunits.valWUnit('fine tol', 'angle', 0.5, 'degrees')

# =============================================================================
# Defaults (will eventually make to a config file)
# =============================================================================

HERE = os.path.dirname(__file__)
toMatFile = os.path.join(HERE, '..', 'data', 'materials.cfg')
DFLT_MATFILE = os.path.normpath(toMatFile)  # check whether it exists
matfileOK = os.access(DFLT_MATFILE, os.F_OK)
if not matfileOK:  # use relative path
    DFLT_MATFILE = os.path.join('data', 'materials.cfg')
    pass
matfileOK = os.access(DFLT_MATFILE, os.F_OK)
if not matfileOK:  # set to null
예제 #39
0
materials are defined by name in materialDict.
"""
from ConfigParser import SafeConfigParser as Parser
import numpy

from hexrd.xrd.crystallography import PlaneData as PData
from hexrd.xrd.spacegroup import SpaceGroup as SG

from hexrd.valunits import valWUnit

#
__all__ = ["Material", "loadMaterialList"]
#
# ================================================== Module Data
#
angstroms = lambda x: valWUnit("lp", "length", x, "angstrom")
degrees = lambda x: valWUnit("lp", "angle", x, "degrees")
#
# ---------------------------------------------------CLASS:  Material
#
class Material(object):
    """Simple class for holding lattice parameters, accessible by name.

    The class references materials by name and contains lattice and
    space group data.
    """

    DFLT_NAME = "material"
    DFLT_SGNUM = 230
    DFLT_LPARMS = [angstroms(1.0), angstroms(1.0), angstroms(1.0), degrees(90.0), degrees(90.0), degrees(90.0)]
    DFLT_SSMAX = 50