Module: xrd.detector¶
24 Classes¶
- class hexrd.xrd.detector.ThreadReadFrame(img, readArgs, castArgs)[source]¶
Bases: threading.Thread
- 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
- getNFrames()[source]¶
number of total frames with real data, not number remaining needed in findSpotsOmegaStack
- 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
- 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
- makeNew()[source]¶
return a clean instance for the same data files useful if want to start reading from the beginning
- 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
- class hexrd.xrd.detector.ReadMar165(mode)[source]¶
Bases: hexrd.xrd.detector.Framer2DRC
placeholder; not yet really implemented
- 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
- 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
- class hexrd.xrd.detector.PeakPV1DAtLoc(*args, **kwargs)[source]¶
Bases: hexrd.xrd.detector.Peak1DAtLoc
the pseudo-Voigt: f = A*( n*fl + (1 - n)*fg )
- 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]¶
- 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
- 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
- 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
- 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
- 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
- getRings(planeData, ranges=False)[source]¶
Return a list of rings for the given hkls
Already filters on the exclusions.
- 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
- 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.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);
- 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);
- 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
13 Functions¶
- 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.getOmegaMMReaderList(readerList, overall=False)[source]¶
get omega min/max information from a list of readers
- 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:
pVecIf *args is (xc, yc, workDist, xTilt, yTilt, zTilt) detector parameters, then additional keyword arguments may include:
distortionParams