Skip to content

Commit f92de8a

Browse files
committed
do spot/point masks via matplotlib Circle artist - much faster & simpler
1 parent 751ea71 commit f92de8a

File tree

3 files changed

+18
-64
lines changed

3 files changed

+18
-64
lines changed

GSASII/GSASIIimage.py

Lines changed: 16 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -793,50 +793,6 @@ def EdgeFinder(image,data):
793793
tay = ma.compressed(ma.array(tay.flatten(),mask=tam))
794794
return zip(tax,tay)
795795

796-
# def MakeFrameMask(data,frame): #obsolete
797-
# '''Assemble a Frame mask for a image, according to the input supplied.
798-
# Note that this requires use of the Fortran polymask routine that is limited
799-
# to 1024x1024 arrays, so this computation is done in blocks (fixed at 512)
800-
# and the master image is assembled from that.
801-
802-
# :param dict data: Controls for an image. Used to find the image size
803-
# and the pixel dimensions.
804-
# :param list frame: Frame parameters, typically taken from ``Masks['Frames']``.
805-
# :returns: a mask array with dimensions matching the image Controls.
806-
# '''
807-
# if GSASIIpath.binaryPath:
808-
# import polymask as pm
809-
# else:
810-
# from . import polymask as pm
811-
# pixelSize = data['pixelSize']
812-
# scalex = pixelSize[0]/1000.
813-
# scaley = pixelSize[1]/1000.
814-
# blkSize = 512
815-
# Nx,Ny = data['size']
816-
# nXBlks = (Nx-1)//blkSize+1
817-
# nYBlks = (Ny-1)//blkSize+1
818-
# tam = ma.make_mask_none(data['size'])
819-
# for iBlk in range(nXBlks):
820-
# iBeg = iBlk*blkSize
821-
# iFin = min(iBeg+blkSize,Nx)
822-
# for jBlk in range(nYBlks):
823-
# jBeg = jBlk*blkSize
824-
# jFin = min(jBeg+blkSize,Ny)
825-
# nI = iFin-iBeg
826-
# nJ = jFin-jBeg
827-
# tax,tay = np.mgrid[iBeg+0.5:iFin+.5,jBeg+.5:jFin+.5] #bin centers not corners
828-
# tax = np.asfarray(tax*scalex,dtype=np.float32)
829-
# tay = np.asfarray(tay*scaley,dtype=np.float32)
830-
# tamp = ma.make_mask_none((1024*1024))
831-
# tamp = ma.make_mask(pm.polymask(nI*nJ,tax.flatten(),
832-
# tay.flatten(),len(frame),frame,tamp)[:nI*nJ])^True #switch to exclude around frame
833-
# if tamp.shape:
834-
# tamp = np.reshape(tamp[:nI*nJ],(nI,nJ))
835-
# tam[iBeg:iFin,jBeg:jFin] = ma.mask_or(tamp[0:nI,0:nJ],tam[iBeg:iFin,jBeg:jFin])
836-
# else:
837-
# tam[iBeg:iFin,jBeg:jFin] = True
838-
# return tam.T
839-
840796
def CalcRings(G2frame,ImageZ,data,masks):
841797
pixelSize = data['pixelSize']
842798
scalex = 1000./pixelSize[0]
@@ -1251,23 +1207,25 @@ def Make2ThetaAzimuthMap(data,iLim,jLim): #most expensive part of integration!
12511207
TA[3] = G2pwd.Polarization(data['PolaVal'][0],TA[0],TA[1]-90.)[0]
12521208
return TA #2-theta, azimuth & geom. corr. arrays
12531209

1254-
def polymask(data,Poly):
1255-
''' Applies polygon & frame masks via calls to matplotlib routines;
1256-
should be called only once during image processing. Individual masked blocks
1257-
are then pulled from the output array.
1210+
def polymask(data,Poly,Spots=[]):
1211+
''' Applies spot(point), polygon & frame masks via calls to matplotlib routines;
1212+
should be called only once each during image processing. A separate call is used for a frame.
1213+
Individual masked blocks are then pulled from the output array.
12581214
12591215
:param dict data: GSAS-II image data object (describes the image)
12601216
:param list Poly: list of polygons; if empty, returns None
1261-
:returns: Zimg, array[Nx,Ny] size of full image mask for all polygons considered
1217+
:param list Spots: list of spots/points; if empty, returns None
1218+
:returns: Zimg, array[Nx,Ny] size of full image mask for all polygons/spots or frame considered
12621219
'''
12631220

12641221
import matplotlib.figure as mplfig
1222+
from matplotlib.patches import Circle
12651223
try:
12661224
from matplotlib.backends.backend_agg import FigureCanvasAgg as hcCanvas
12671225
except ImportError:
12681226
from matplotlib.backends.backend_agg import FigureCanvas as hcCanvas # standard name
12691227

1270-
if not Poly:
1228+
if not Poly and not Spots:
12711229
return []
12721230
outmask = 'black'
12731231
inmask = 'white'
@@ -1285,6 +1243,12 @@ def polymask(data,Poly):
12851243
px = np.array(poly).T[0]/scalex
12861244
py = np.array(poly).T[1]/scaley
12871245
ax0.fill(px,py,inmask)
1246+
for spot in Spots:
1247+
px = np.array(spot).T[0]/scalex
1248+
py = np.array(spot).T[1]/scaley
1249+
rad = 0.5*np.array(spot).T[2]/scaley
1250+
psp = Circle((px,py),radius=rad,fc=inmask,ec='none')
1251+
ax0.add_artist(psp)
12881252
ax0.set_xbound(0,Nx)
12891253
ax0.set_ybound(0,Ny)
12901254
img, (width,height) = canvas.print_to_buffer()
@@ -1296,7 +1260,7 @@ def MakeMaskMap(data,masks,iLim,jLim):
12961260
image calibration parameters or the image intensities. Thus this uses
12971261
mask Frames, Polygons and Lines settings (but not Thresholds, Rings or
12981262
Arcs). Used on a rectangular section of an image (must be 1024x1024 or
1299-
smaller, as dictated by module polymask) where the size is determined
1263+
smaller) where the size is determined
13001264
by iLim and jLim.
13011265
13021266
:param dict data: GSAS-II image data object (describes the image)
@@ -1313,7 +1277,7 @@ def MakeMaskMap(data,masks,iLim,jLim):
13131277
if masks['Frames']:
13141278
frame = np.abs(polymask(data,masks['Frames'])-255) #turn inner to outer mask
13151279
if masks['Polygons']:
1316-
poly = polymask(data,masks['Polygons'])
1280+
poly = polymask(data,masks['Polygons'],masks['Points'])
13171281
if len(frame):
13181282
masks['Pmask'] = frame
13191283
if len(poly):
@@ -1331,10 +1295,6 @@ def MakeMaskMap(data,masks,iLim,jLim):
13311295
tam = ma.make_mask_none((nI*nJ))
13321296
if len(masks['Pmask']):
13331297
tam = ma.mask_or(tam,ma.make_mask(masks['Pmask'][iLim[0]:iLim[1],jLim[0]:jLim[1]].flatten()))
1334-
points = masks['Points']
1335-
if len(points):
1336-
for X,Y,rsq in points.T:
1337-
tam = ma.mask_or(tam,ma.getmask(ma.masked_less((tax-X)**2+(tay-Y)**2,rsq)))
13381298
if tam.shape:
13391299
tam = np.reshape(tam,(nI,nJ))
13401300
else:
@@ -1449,9 +1409,6 @@ def MakeUseMask(data,masks,blkSize=128):
14491409
:returns: a list of TA blocks
14501410
'''
14511411
Masks = copy.deepcopy(masks)
1452-
Masks['Points'] = np.array(Masks['Points']).T #get spots as X,Y,R arrays
1453-
if np.any(masks['Points']):
1454-
Masks['Points'][2] = np.square(Masks['Points'][2]/2.)
14551412
Nx,Ny = data['size']
14561413
nXBlks = (Nx-1)//blkSize+1
14571414
nYBlks = (Ny-1)//blkSize+1
@@ -1599,9 +1556,6 @@ def ImageIntegrate(image,data,masks,blkSize=128,returnN=False,useTA=None,useMask
15991556
if 'SASD' in data['type']:
16001557
muT = -np.log(muT)/2. #Transmission to 1/2 thickness muT
16011558
Masks = copy.deepcopy(masks)
1602-
Masks['Points'] = np.array(Masks['Points']).T #get spots as X,Y,R arrays
1603-
if np.any(masks['Points']):
1604-
Masks['Points'][2] = np.square(Masks['Points'][2]/2.)
16051559
NST = np.zeros(shape=(numAzms,numChans),order='F',dtype=np.float32)
16061560
H0 = np.zeros(shape=(numAzms,numChans),order='F',dtype=np.float32)
16071561
H2 = np.linspace(lutth[0],lutth[1],numChans+1)

GSASII/GSASIIimgGUI.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ def OnPolaCalib(event):
254254
################################################################################
255255
##### Image Controls
256256
################################################################################
257-
blkSize = 128 #128 seems to be optimal; will break in polymask if >1024
257+
blkSize = 128 #128 seems to be optimal
258258
def UpdateImageControls(G2frame,data,masks,useTA=None,useMask=None,IntegrateOnly=False):
259259
'''Shows and handles the controls on the "Image Controls"
260260
data tree entry

GSASII/GSASIIscriptable.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6170,7 +6170,7 @@ def Export(self,fileroot,extension,fmthint=None):
61706170

61716171
blkSize = 128
61726172
'''Integration block size; 128 or 256 seems to be optimal for CPU use, but 128 uses
6173-
less memory, must be <=1024 (for polymask/histogram3d)
6173+
less memory, must be <=1024 (for histogram3d)
61746174
'''
61756175

61766176
def calcMaskMap(imgprms,mskprms):

0 commit comments

Comments
 (0)