Module: xrd.detector

24 Classes

class hexrd.xrd.detector.FmtCoordIdeal(planeData, workDist)[source]
__init__(planeData, workDist)[source]
class hexrd.xrd.detector.ThreadReadFrame(img, readArgs, castArgs)[source]

Bases: threading.Thread

__init__(img, readArgs, castArgs)[source]
class hexrd.xrd.detector.Framer2DRC(ncols, nrows, dtypeDefault='int16', dtypeRead='uint16', dtypeFloat='float64')[source]

Bases: object

Base class for readers.

You can make an instance of this class and use it for most of the things a reader would do, other than actually reading frames

__init__(ncols, nrows, dtypeDefault='int16', dtypeRead='uint16', dtypeFloat='float64')[source]
getDark()[source]

needed in findSpotsOmegaStack

getDeltaOmega()[source]

needed in findSpotsOmegaStack

getEmptyMask()[source]

convenience method for getting an emtpy mask or bin frame

getFrameOmega(iFrame=None)[source]

needed in findSpotsOmegaStack

getNFrames()[source]

number of total frames with real data, not number remaining needed in findSpotsOmegaStack

classmethod maxVal(dtypeRead)[source]

maximum value that can be stored in the image pixel data type; redefine as desired

read(nskip=0, nframes=1, sumImg=False)[source]

needed in findSpotsOmegaStack

class hexrd.xrd.detector.FrameWriter(*args, **kwargs)[source]

Bases: hexrd.xrd.detector.Framer2DRC

__init__(*args, **kwargs)[source]
class hexrd.xrd.detector.ReadGeneric(filename, ncols, nrows, *args, **kwargs)[source]

Bases: hexrd.xrd.detector.Framer2DRC

may eventually want ReadGE to inherit from this, or pull common things off to a base class

__init__(filename, ncols, nrows, *args, **kwargs)[source]
getDark()[source]

no dark yet supported

getFrameOmega(iFrame=None)[source]

if iFrame is none, use internal counter

makeNew()[source]

return a clean instance for the same data files useful if want to start reading from the beginning

read(nskip=0, nframes=1, sumImg=False)[source]

sumImg can be set to True or to something like numpy.maximum

subtractDark = None

keep things for makeNew convenience

class hexrd.xrd.detector.ReadGE(fileInfo, *args, **kwargs)[source]

Bases: hexrd.xrd.detector.Framer2DRC

Read in raw GE files; this is the class version of the foregoing functions

NOTES

*) The flip axis (‘v’ertical) was verified on 06 March 2009 by
JVB and UL. This should be rechecked if the configuration of the GE changes or you are unsure.
*) BE CAREFUL! nframes should be < 10 or so, or you will run out of
memory in the namespace on a typical machine.

*) The header is currently ignored

*) If a dark is specified, this overrides the use of empty frames as
background; dark can be a file name or frame
*) In multiframe images where background subtraction is requested but no
dark is specified, attempts to use the empty frame(s). An error is returned if there are not any specified. If there are multiple empty frames, the average is used.
__init__(fileInfo, *args, **kwargs)[source]

meant for reading a series of frames from an omega sweep, with fixed delta-omega for each frame

omegaStart and omegaDelta can follow fileInfo or be specified in whatever order by keyword

fileInfo: string, (string, nempty), or list of (string, nempty) for multiple files

for multiple files and no dark, dark is formed only from empty frames in the first file

classmethod display(thisframe, roi=None, pw=None, **kwargs)[source]

this is a bit ugly in that it sidesteps the dtypeRead property

getFrameOmega(iFrame=None)[source]

if iFrame is none, use internal counter

getFrameUseMask()[source]

this is an optional toggle to turn the mask on/off

getNFrames()[source]

number of total frames with real data, not number remaining

indicesToMask(indices)[source]

Indices can be a list of indices, as from makeIndicesTThRanges

makeNew()[source]

return a clean instance for the same data files useful if want to start reading from the beginning

classmethod maxVal(dummy)[source]

maximum value that can be stored in the image pixel data type

rawRead(*args, **kwargs)[source]

wrapper around readRaw that does the same flipping as the reader instance from which it is called

read(nskip=0, nframes=1, sumImg=False, mask=None)[source]

sumImg can be set to True or to something like numpy.maximum

readBBox(bbox, raw=True, doFlip=None)[source]

with raw=True, read more or less raw data, with bbox = [(iLo,iHi),(jLo,jHi),(fLo,fHi)]

careful: if raw is True, must set doFlip if want frames potentially flipped; can set it to a reader instance to pull the doFlip value from that instance

classmethod readDark(darkFile, nframes=1)[source]

dark subtraction is done before flipping, so do not flip when reading either

classmethod readRaw(fname, mode='raw', headerlen=0)[source]

read a raw binary file; if specified, headerlen is in bytes; does not do any flipping

useThreading[source]

turn threading on or off

class hexrd.xrd.detector.ReadMar165(mode)[source]

Bases: hexrd.xrd.detector.Framer2DRC

placeholder; not yet really implemented

__init__(mode)[source]
class hexrd.xrd.detector.ReadMar165NB1(*args, **kwargs)[source]

Bases: hexrd.xrd.detector.ReadMar165

__init__(*args, **kwargs)[source]
class hexrd.xrd.detector.ReadMar165NB2(*args, **kwargs)[source]

Bases: hexrd.xrd.detector.ReadMar165

__init__(*args, **kwargs)[source]
class hexrd.xrd.detector.ReadMar165NB3(*args, **kwargs)[source]

Bases: hexrd.xrd.detector.ReadMar165

__init__(*args, **kwargs)[source]
class hexrd.xrd.detector.ReadMar165NB4(*args, **kwargs)[source]

Bases: hexrd.xrd.detector.ReadMar165

__init__(*args, **kwargs)[source]
class hexrd.xrd.detector.LineStyles(lt=None)[source]

do not want to just cycle through default plot line colors, as end up with black lines

__init__(lt=None)[source]
class hexrd.xrd.detector.Peak1DAtLoc(centers, xVecDflt=None)[source]

base class for 1D peak shapes at fixed location; fixed that is unless newCenter is passed to the __call__ method

__init__(centers, xVecDflt=None)[source]

If __init__ is called with a list, then put one peak at each location

d_dCenters(xVec, p)[source]

derivative of call with respect to centers

d_dp(xVec, p)[source]

derivative of call with respect to p assuming each eval depends only on its own point!

d_dx(xVec, p)[source]

derivative of call with respect to xVec

eval(xVec, p)[source]

xVec is parameters, p is positions

fitFloatingCenter(tThVals, intensityVals, xVecGuess=None, centersGuess=None, weights=4, tThWidth=None, fitGoodnessTol=0.5)[source]

Note that centers are kept as they are – if you want to actually change the centers of the function you need to call setCenters(cFit) after calling this function

class hexrd.xrd.detector.PeakPV1DAtLoc(*args, **kwargs)[source]

Bases: hexrd.xrd.detector.Peak1DAtLoc

the pseudo-Voigt: f = A*( n*fl + (1 - n)*fg )

__init__(*args, **kwargs)[source]
d_dx(xVec, p)[source]

allow p to be general shape

class hexrd.xrd.detector.PeakLorentzian1DAtLoc(*args, **kwargs)[source]

Bases: hexrd.xrd.detector.Peak1DAtLoc

__init__(*args, **kwargs)[source]
d_dx(xVec, p)[source]

allow p to be general shape

getNParams()[source]

2 parameters for background, 2 for intensity and width of each peak

class hexrd.xrd.detector.PeakGauss1DAtLoc(*args, **kwargs)[source]

Bases: hexrd.xrd.detector.Peak1DAtLoc

__init__(*args, **kwargs)[source]
d_dCenters(xVec, p)[source]

allow p to be general shape

d_dx(xVec, p)[source]

allow p to be general shape

getNParams()[source]

2 parameters for background, 2 for intensity and width of each peak

class hexrd.xrd.detector.MultiRingBinned(detectorGeom, planeData, dataFrame, funcType='pv', refineParamsDG=True, refineParamsL=False, targetNRho=None, polarRebinKWArgs={}, quadr=4, npdivMax=8, samplingFactor=1, singleRebin=True, distortionFreeRefDG=False, log=None)[source]

like MultiRingEval, but works with polar rebinned (or ‘caked’) images

no funcXVecList to init because expectation is that always pulled from dataFrame

should work fine whether or not corrected is True in polarRebinKWArgs; but note that default is changed to True

if etaRange is not specified in polarRebinKWArgs (or is None), then the etaRange is calculated based on numEta so that the first eta bin is centered around an angle of zero

note that this works by matching intesities for binned 1D functions in a least sqaures problem; one could probably instead form a residual on the two-theta values of the image frame positions for the peak centers found with independtly floating centers (on the output of the getTThErrors method)

KEYWORD ARGS

funcType = funcTypeDflt, refineParamsDG = True, refineParamsL = False, targetNRho = 30, polarRebinKWArgs = {}, quadr = 4, npdivMax = 4, samplingFactor = 0.25, singleRebin = True, distortionFreeRefDG = False, log=None: if not None, then a file-like object with a “write” method;

__init__(detectorGeom, planeData, dataFrame, funcType='pv', refineParamsDG=True, refineParamsL=False, targetNRho=None, polarRebinKWArgs={}, quadr=4, npdivMax=8, samplingFactor=1, singleRebin=True, distortionFreeRefDG=False, log=None)[source]
doFit(xVec0=None, **lsKWArgs)[source]

lsKWArgs can have things like ftol and xtol for leastsq

eval(xVec)[source]

careful: this updates the settings in detectorGeom and planeData

floatingCentersIJ = None

make a reference detector geom

getTThErrors(plot=False, units='strain', outputFile=None)[source]

convenient way of looking at the errors, though not how the errors are actually measured in the fitting procedure; get the tTh values at the image frame locations deemed to be the centers with the floating-center fits

units can be: ‘mm’ <radius>, ‘d-spacing’, ‘strain’, ‘radians’ <tTh>, ‘degrees’ <tTh>

logfile

file for log messages

plotByRingEta(iRingSet, iEta, win=None, sqrtIntensity=True, alpha=0.25)[source]

may have redundant work here, but assume this is not a big deal if doing plots

polImg = None

tth values for figuring out where the rings fall

prbkw = None

things from the user

rhoPxRange = None

and now compute number of rho bins across all ring sets

ticMethod = None

defaults which want different from those for polarRebin’s defaults

wQP = None

leastsq to do fit, with floating center

class hexrd.xrd.detector.MultiRingEval(detectorGeom, planeData, indicesList=None, iHKLLists=None, dataFrame=None, funcType='pv', refineParamsDG=True, refineParamsL=False, funcXVecList=None, copyFrame=False, quadr=3)[source]

For working with data as rings, particularly for fitting detector geometry or lattice parameters.

__init__(detectorGeom, planeData, indicesList=None, iHKLLists=None, dataFrame=None, funcType='pv', refineParamsDG=True, refineParamsL=False, funcXVecList=None, copyFrame=False, quadr=3)[source]

Mostly meant for use with DetectorGeomGE.fit

If funcXVecList is passed, then entries in this list are used for peak function forms, and these peak function forms do not appear in the degrees of freedom

Note that ranges for 2-thetas from planeData need to be such that rings are adequately covered

Can optionally pass indicesList and iHKLLists if they are already handy

if copyFrame is True, then data in dataFrame is copied

deval(xVec)[source]

useful to pass, for example, as Dfun to leastsq; bit of a misnomer in that deval is the derivative of __call__, not eval

doFit(xVec0=None, **lsKWArgs)[source]

lsKWArgs can have things like ftol and xtol for leastsq

eval(xVec, thisframe=None)[source]

if thisframe is passed, the put values on the frame

jQP = None

do not worry about dvQP kinds of contributions for now

radialFitXVec(dataFrame=None, plot=False, plotTitlePrefix='', quadr1d=None)[source]

if dataFrame is not provided, use self.dataFrame

if quadr1d is not specified, use quadr specified in init

radialPlotData(dataFrame=None, plotTitlePrefix='')[source]

for simple radial plotting, useful if other things are mysteriously breaking

setFuncXVecList(funcXVecList)[source]

only okay if funcXVecList set on init

class hexrd.xrd.detector.DetectorBase(reader)[source]

Bases: object

base class for a detector

__init__(reader)[source]
getPVecScaling()[source]

scaling, suitable for scaling perturbations for finite differencing

getParamScalings()[source]

scalings, suitable for scaling perturbations for finite differencing

class hexrd.xrd.detector.Detector2DRC(ncols, nrows, pixelPitch, vFactorUnc, vDark, reader, *args, **kwargs)[source]

Bases: hexrd.xrd.detector.DetectorBase

base class for 2D row-column detectors

__init__(ncols, nrows, pixelPitch, vFactorUnc, vDark, reader, *args, **kwargs)[source]
angOnDetector(tTh, eta, *args)[source]

note: returns a scalar if tTh and eta have single entries

angToXYO(x0, y0, *args, **kwargs)[source]

convert Cartesian to polar

uses blocking to call vectorized version

angToXYOBBox(*args, **kwargs)[source]

given either angBBox or angCOM (angular center) and angPM (+-values), compute the bounding box on the image frame

if forSlice=True, then returned bbox is appropriate for use in array slicing

if reader or omegas is passed, then convert from omegas to frames; and if doWrap=True, then frames may be a list for an omega range that spans the branch cut

angToXYO_V(tth, eta_l, *args, **kwargs)[source]

opposite of xyoToAng

cartesianCoordsOfPixelIndices(row, col, ROI=None)[source]

converts [i, j] pixel array indices to cartesian spatial coords where the lower left corner of the image is (0, 0)

Output units are in the pixel pitch units (see self.pixelPitch)

Will optionally take the upper left-hand corner (min row, min col) of a ROI when dealing with subregions on the detector as in when zooming in on diffraction spots...

*) explicitly enforce this to be self-consistent with radial distortion correction, etc...

display(thisframe, planeData=None, **kwargs)[source]

wrap reader display method; display coordinates as 2-theta and eta given that self knows how to do this

if pass planeData, then it is used to list HKLs overlapping the given 2-theta location

...*** option for drawing lab-frame glyph

displayIdeal(thisframe, planeData=None, workDist=None, nlump=None, **kwargs)[source]

render and display frame on ideal detector plane; if workDist is not specified, then use self.workDist

drawRings(drawOn, planeData, withRanges=False, legendLoc=(0.05, 0.5), legendMaxLen=10, ideal=None, range=None, lineType=None, lineWidth=1.0)[source]

If drawOn is a PlotWrap instance, draw on the existing instance, otherwise pass drawOn to display and return the resulting PlotWrap instance

planeData.exclusions can be used to work with a subset of rings;

set legendLoc to None or False to skip making the legend

removes any existing lines in the axes

if pass ideal, then display rings on an ideal detector with the working distance taken from the value of the ideal argument

drawRingsGUI(thisframe, planeData, displayKWArgs={}, sliderRangeFactor=1.0, funcType='pv')[source]

a simple GUI

getAngPixelSize(xyo, delta_omega)[source]

get pixel size in angular coordinates at a given cartesian coordinate position

getPRBOverlay(polarRebinKWArgs)[source]

Return plottable coordinates of rebinning sector.

Takes in dictionary of keyword args for polarRebin

for etas, right now assumes stopEta > startEta, CCW

getParamScalings()[source]

scalings, suitable for scaling perturbations for finite differencing

getRings(planeData, ranges=False)[source]

Return a list of rings for the given hkls

Already filters on the exclusions.

getVScale(vThese)[source]

get scale factors for use in uncertainty quantification

makeIndicesTThRanges(planeData, cullDupl=False)[source]

return a list of indices for sets of overlaping two-theta ranges; to plot, can do something like:

mask = self.reader.getEmptyMask()

mask[indices] = True

With cullDupl set true, eliminate HKLs with duplicate 2-thetas

makeMaskTThRanges(planeData)[source]

Mask in the sense that reader with the mask will exclude all else

pixelIndicesOfCartesianCoords(x, y, ROI=None)[source]

converts [i, j] pixel array indices to cartesian spatial coords where the lower left corner of the image is (0, 0)

Output units are in the pixel pitch units (see self.pixelPitch)

Will optionally take the upper left-hand corner (min row, min col) of a ROI when dealing with subregions on the detector as in when zooming in on diffraction spots...

*) explicitly enforce this to be self-consistent with radial distortion correction, etc...

polarRebin(thisFrame, npdiv=2, rhoRange=[100, 1000], numRho=1200, etaRange=array([-0.08726646, 6.19591884]), numEta=36, ROI=None, corrected=False, verbose=True, log=None)[source]

Caking algorithm

INPUTS

thisFrame npdiv=2, pixel subdivision (n x n) to determine bin membership rhoRange=[100, 1000] - radial range in pixels numRho=1200 - number of radial bins etaRange=num.pi*num.r_[-5, 355]/180. – range of eta numEta=36 - number of eta subdivisions ROI=None - region of interest (four vector) corrected=False - uses 2-theta instead of rho verbose=True,

renderIdeal(thisframe, nlump=None, workDist=None)[source]

render the frame on an ideal detector plane; returns interpolated frame data zi on a regular grid xi, yi; suitable for use with pcolormesh(xim, yim, zi), with xim, yim = num.meshgrid(xi, yi); note that pcolormesh is used instead of pcolor because zi may be a masked array

xyoToAng(x0, y0, *args, **kwargs)[source]

convert Cartesian to polar

uses blocking to call vectorized version

xyoToAngAll()[source]

get angular positions of all pixels

xyoToAngCorners()[source]

get angular positions of corner pixels

xyoToAngMap(x0, y0, *args, **kwargs)[source]

eta by default is in [-pi,pi] if all data are in the left quadrants, remap eta into [0,2*pi]

xyoToAng_V(x0, y0, *args, **kwargs)[source]

Convert radial spectra obtained from polar rebinned powder diffraction images to angular spectra.

USAGE: mappedData = XFormRadialSpectra(t, D, tilt, xydata, azim, tthRange, radDistFuncHandle, radDistArgs)

INPUTS:

1) t is 2 x 1 (double), the origin translation. The convention is from `true’ to `estimated’ centers. 2) D is 1 x 1 (double), the sample-to-detector distance in mm. 3) gammaYprime is 1 x 1 (double), the angle between the `ideal’ and `experimental’ X-axes (horizontal). 4) gammaXhatPrime is 1 x 1 (double), the angle between the `ideal’ and `experimental’ Y-axes (vertical). 5) xydata is 1 x n (cell), the cell array of data 6) azim 7) tthRange 8) radDistFuncHandle

OUTPUT:

1) mappedData is 1 x n (cell), the cell array of mapped radial data corresponding to the input `xydata’.

class hexrd.xrd.detector.DetectorGeomMar165(*args, **kwargs)[source]

Bases: hexrd.xrd.detector.Detector2DRC

__init__(*args, **kwargs)[source]
radialDistortion(xin, yin, invert=False)[source]

no distortion correction

class hexrd.xrd.detector.DetectorGeomGE(*args, **kwargs)[source]

Bases: hexrd.xrd.detector.Detector2DRC

handle geometry of GE detector, such as geometric and radial distortion corrections; x and y are in pixels, as is rho; pixels are numbered from (0,0);

__init__(*args, **kwargs)[source]
radialDistortion(xin, yin, invert=False)[source]

Apply radial distortion to polar coordinates on GE detector

xin, yin are 1D arrays or scalars, assumed to be relative to self.xc, self.yc Units are [mm, radians]. This is the power-law based function of Bernier.

Available Keyword Arguments :

invert = True or >False< :: apply inverse warping

class hexrd.xrd.detector.DetectorGeomFrelon(*args, **kwargs)[source]

Bases: hexrd.xrd.detector.Detector2DRC

handle geometry of GE detector, such as geometric and radial distortion corrections; x and y are in pixels, as is rho; pixels are numbered from (0,0);

__init__(*args, **kwargs)[source]
radialDistortion(xin, yin, invert=False)[source]

Apply radial distortion to polar coordinates on GE detector

xin, yin are 1D arrays or scalars, assumed to be relative to self.xc, self.yc Units are [mm, radians]. This is the power-law based function of Bernier.

(p[0]*(ri/rx)**p[3] * num.cos(2.0 * ni) + p[1]*(ri/rx)**p[4] * num.cos(4.0 * ni) + p[2]*(ri/rx)**p[5] + 1)*ri

1 + p[0]*(ri/rx)**p[2] * num.cos(p[4] * ni) + p[1]*(ri/rx)**p[3]

Available Keyword Arguments :

invert = True or >False< :: apply inverse warping

class hexrd.xrd.detector.DetectorGeomQuadGE(*args, **kwargs)[source]

Bases: hexrd.xrd.detector.DetectorBase

No global parameters – all detector parameters hang off of the sub-detectors; although some data are stored off of this higher level class for convenience

__init__(*args, **kwargs)[source]

pass ReadGE instance as the reader for now; perhaps make a ReadQuadGE class later if it turns out to be needed

dgDummy = None

cleanup after auto-parsing of keyword args

displayIdeal(framesQuad, planeData=None, workDist=None, nlump=None, doFmtCoord=True, **kwargs)[source]

display all sub-detectors on an idealized detector plane

If matplotlib gets around to enabling the transform argument to imshow, that might be a much faster approach than what is currently done here, although what is done here is nice in that it takes account of all of the distortions, not just the in-plane rotation. The idea would be that the in-plane rotation would be, by far, the biggest effect. import matplotlib.transforms as mtransforms tr = mtransforms.Affine2D() tr.rotate(self.zTilt) imshow( , transform=tr)

displaySub(iQuad, thisframe, planeData=None, **kwargs)[source]

convenience for displaying a sub-detector ...*** need to code labAxesGlyph support in display

drawRings(drawOn, planeData, workDist=None, **kwargs)[source]

assumes ideal geometry, as from displayIdeal

fitProcedureA(planeData, framesQuad, iRefQuad=0, funcType='pv', funcXVecList=None, quadr=1, doGUI=0, doMRingPlot=False)[source]

A procedure for fitting the set of detectors; do not need to click ‘fit’ button in GUI – done inside the procedure.

Watch out – MultiRingEval instances a memory hogs, especially while creating Jacobian matrices!

If want to just refine detector geometry and not the functional forms for the rings, pass funcXVecList as True or as something like a list of arrays from MultiRingEval.getFuncXVecList()

classmethod getRefineFlagsDflt()[source]

no parameters to refine for this detector; call fitProcedureA for a procedure to refine individual sub-detectors

getTThMax()[source]

min over sub-detectors, where for each sub-detector max two-theta is evaluated as the max over points checked in getTThMax for the sub-detector

setCentersFromRef(iRefQuad=0)[source]

this assumes all of the tilts are the same

setQuadOffsets(iRefQuad=0)[source]

this assumes all of the tilts are the same

13 Functions

hexrd.xrd.detector.angToXYIdeal(tTh, eta, workDist)[source]
hexrd.xrd.detector.mapAngs(eta, doMap=None)[source]
hexrd.xrd.detector.getCentered(vmin, vmax)[source]
hexrd.xrd.detector.getCMap(spec)[source]
hexrd.xrd.detector.omeRangeToFrameRange(omeA, omeB, omegaStart, omegaDelta, nFrames, checkWrap=True, slicePad=1)[source]

assumes omegas are evenly spaced omegaDelta may be negative

hexrd.xrd.detector.frameInRange(iFrame, frameRange)[source]

for use with output from omeRangeToFrameRange; trust that slicePad=1 was used in omeRangeToFrameRange

hexrd.xrd.detector.getNFramesFromBytes(fileBytes, nbytesHeader, nbytesFrame)[source]
hexrd.xrd.detector.mar165IDim(mode)[source]
hexrd.xrd.detector.getOmegaMMReaderList(readerList, overall=False)[source]

get omega min/max information from a list of readers

hexrd.xrd.detector.detectorList()[source]
hexrd.xrd.detector.newDetector(detectorType, *args, **kwargs)[source]

Return a detector of the requested type

INPUTS

detectorType - a string in the detector type list [see detectorList()]

hexrd.xrd.detector.newGenericReader(ncols, nrows, *args, **kwargs)[source]

currently just returns a Framer2DRC

hexrd.xrd.detector.newGenericDetector(ncols, nrows, pixelPitch, *args, **kwargs)[source]

If reader is passed as None, then a generic reader is created

Keyword Arguments:
vFactorUnc vDark reader readerKWArgs getDParamDflt setDParamZero getDParamScalings getDParamRefineDflt radialDistortion

If *args is an existing detector geometry, then additional keyword arguments may include:

pVec

If *args is (xc, yc, workDist, xTilt, yTilt, zTilt) detector parameters, then additional keyword arguments may include:

distortionParams