@@ -788,50 +788,50 @@ def EdgeFinder(image,data):
788
788
tax = ma .compressed (ma .array (tax .flatten (),mask = tam ))
789
789
tay = ma .compressed (ma .array (tay .flatten (),mask = tam ))
790
790
return zip (tax ,tay )
791
-
792
- def MakeFrameMask (data ,frame ):
793
- '''Assemble a Frame mask for a image, according to the input supplied.
794
- Note that this requires use of the Fortran polymask routine that is limited
795
- to 1024x1024 arrays, so this computation is done in blocks (fixed at 512)
796
- and the master image is assembled from that.
797
-
798
- :param dict data: Controls for an image. Used to find the image size
799
- and the pixel dimensions.
800
- :param list frame: Frame parameters, typically taken from ``Masks['Frames']``.
801
- :returns: a mask array with dimensions matching the image Controls.
802
- '''
803
- if GSASIIpath .binaryPath :
804
- import polymask as pm
805
- else :
806
- from . import polymask as pm
807
- pixelSize = data ['pixelSize' ]
808
- scalex = pixelSize [0 ]/ 1000.
809
- scaley = pixelSize [1 ]/ 1000.
810
- blkSize = 512
811
- Nx ,Ny = data ['size' ]
812
- nXBlks = (Nx - 1 )// blkSize + 1
813
- nYBlks = (Ny - 1 )// blkSize + 1
814
- tam = ma .make_mask_none (data ['size' ])
815
- for iBlk in range (nXBlks ):
816
- iBeg = iBlk * blkSize
817
- iFin = min (iBeg + blkSize ,Nx )
818
- for jBlk in range (nYBlks ):
819
- jBeg = jBlk * blkSize
820
- jFin = min (jBeg + blkSize ,Ny )
821
- nI = iFin - iBeg
822
- nJ = jFin - jBeg
823
- tax ,tay = np .mgrid [iBeg + 0.5 :iFin + .5 ,jBeg + .5 :jFin + .5 ] #bin centers not corners
824
- tax = np .asfarray (tax * scalex ,dtype = np .float32 )
825
- tay = np .asfarray (tay * scaley ,dtype = np .float32 )
826
- tamp = ma .make_mask_none ((1024 * 1024 ))
827
- tamp = ma .make_mask (pm .polymask (nI * nJ ,tax .flatten (),
828
- tay .flatten (),len (frame ),frame ,tamp )[:nI * nJ ])^ True #switch to exclude around frame
829
- if tamp .shape :
830
- tamp = np .reshape (tamp [:nI * nJ ],(nI ,nJ ))
831
- tam [iBeg :iFin ,jBeg :jFin ] = ma .mask_or (tamp [0 :nI ,0 :nJ ],tam [iBeg :iFin ,jBeg :jFin ])
832
- else :
833
- tam [iBeg :iFin ,jBeg :jFin ] = True
834
- return tam .T
791
+
792
+ # def MakeFrameMask(data,frame): #obsolete
793
+ # '''Assemble a Frame mask for a image, according to the input supplied.
794
+ # Note that this requires use of the Fortran polymask routine that is limited
795
+ # to 1024x1024 arrays, so this computation is done in blocks (fixed at 512)
796
+ # and the master image is assembled from that.
797
+
798
+ # :param dict data: Controls for an image. Used to find the image size
799
+ # and the pixel dimensions.
800
+ # :param list frame: Frame parameters, typically taken from ``Masks['Frames']``.
801
+ # :returns: a mask array with dimensions matching the image Controls.
802
+ # '''
803
+ # if GSASIIpath.binaryPath:
804
+ # import polymask as pm
805
+ # else:
806
+ # from . import polymask as pm
807
+ # pixelSize = data['pixelSize']
808
+ # scalex = pixelSize[0]/1000.
809
+ # scaley = pixelSize[1]/1000.
810
+ # blkSize = 512
811
+ # Nx,Ny = data['size']
812
+ # nXBlks = (Nx-1)//blkSize+1
813
+ # nYBlks = (Ny-1)//blkSize+1
814
+ # tam = ma.make_mask_none(data['size'])
815
+ # for iBlk in range(nXBlks):
816
+ # iBeg = iBlk*blkSize
817
+ # iFin = min(iBeg+blkSize,Nx)
818
+ # for jBlk in range(nYBlks):
819
+ # jBeg = jBlk*blkSize
820
+ # jFin = min(jBeg+blkSize,Ny)
821
+ # nI = iFin-iBeg
822
+ # nJ = jFin-jBeg
823
+ # tax,tay = np.mgrid[iBeg+0.5:iFin+.5,jBeg+.5:jFin+.5] #bin centers not corners
824
+ # tax = np.asfarray(tax*scalex,dtype=np.float32)
825
+ # tay = np.asfarray(tay*scaley,dtype=np.float32)
826
+ # tamp = ma.make_mask_none((1024*1024))
827
+ # tamp = ma.make_mask(pm.polymask(nI*nJ,tax.flatten(),
828
+ # tay.flatten(),len(frame),frame,tamp)[:nI*nJ])^True #switch to exclude around frame
829
+ # if tamp.shape:
830
+ # tamp = np.reshape(tamp[:nI*nJ],(nI,nJ))
831
+ # tam[iBeg:iFin,jBeg:jFin] = ma.mask_or(tamp[0:nI,0:nJ],tam[iBeg:iFin,jBeg:jFin])
832
+ # else:
833
+ # tam[iBeg:iFin,jBeg:jFin] = True
834
+ # return tam.T
835
835
836
836
def CalcRings (G2frame ,ImageZ ,data ,masks ):
837
837
pixelSize = data ['pixelSize' ]
@@ -868,7 +868,7 @@ def CalcRings(G2frame,ImageZ,data,masks):
868
868
frame = masks ['Frames' ]
869
869
tam = ma .make_mask_none (ImageZ .shape )
870
870
if frame :
871
- tam = ma .mask_or (tam ,MakeFrameMask ( data ,frame ))
871
+ tam = ma .mask_or (tam ,ma . make_mask ( np . abs ( polymask ( data ,frame ) - 255 ) ))
872
872
for iH ,H in enumerate (HKL ):
873
873
if debug : print (H )
874
874
dsp = H [3 ]
@@ -946,7 +946,7 @@ def ImageRecalibrate(G2frame,ImageZ,data,masks,getRingsOnly=False):
946
946
frame = masks ['Frames' ]
947
947
tam = ma .make_mask_none (ImageZ .shape )
948
948
if frame :
949
- tam = ma .mask_or (tam ,MakeFrameMask ( data ,frame ))
949
+ tam = ma .mask_or (tam ,ma . make_mask ( np . abs ( polymask ( data ,frame ) - 255 ) ))
950
950
for iH ,H in enumerate (HKL ):
951
951
if debug : print (H )
952
952
dsp = H [3 ]
@@ -1247,9 +1247,51 @@ def Make2ThetaAzimuthMap(data,iLim,jLim): #most expensive part of integration!
1247
1247
TA [3 ] = G2pwd .Polarization (data ['PolaVal' ][0 ],TA [0 ],TA [1 ]- 90. )[0 ]
1248
1248
return TA #2-theta, azimuth & geom. corr. arrays
1249
1249
1250
- def MakeMaskMap (data ,masks ,iLim ,jLim ,tamp ):
1251
- '''Makes a mask array from masking parameters that are not determined by
1252
- image calibration parameters or the image intensities. Thus this uses
1250
+ def polymask (data ,Poly ):
1251
+ ''' Applies polygon & frame masks via calls to matplotlib routines;
1252
+ should be called only once during image processing. Individual masked blocks
1253
+ are then pulled from the output array.
1254
+
1255
+ :param dict data: GSAS-II image data object (describes the image)
1256
+ :param list Poly: list of polygons; if empty, returns None
1257
+ :returns: Zimg, array[Nx,Ny] size of full image mask for all polygons considered
1258
+ '''
1259
+
1260
+ import matplotlib .figure as mplfig
1261
+ try :
1262
+ from matplotlib .backends .backend_agg import FigureCanvasAgg as hcCanvas
1263
+ except ImportError :
1264
+ from matplotlib .backends .backend_agg import FigureCanvas as hcCanvas # standard name
1265
+
1266
+ if not Poly :
1267
+ return []
1268
+ outmask = 'black'
1269
+ inmask = 'white'
1270
+ Nx ,Ny = data ['size' ]
1271
+ pixelSize = data ['pixelSize' ]
1272
+ scalex = pixelSize [0 ]/ 1000.
1273
+ scaley = pixelSize [1 ]/ 1000.
1274
+ figure = mplfig .Figure (figsize = (Nx / 400. ,Ny / 400. ),dpi = 400 ,facecolor = outmask )
1275
+ canvas = hcCanvas (figure )
1276
+ figure .clf ()
1277
+ ax0 = figure .add_subplot ()
1278
+ ax0 .axis ("off" )
1279
+ figure .subplots_adjust (bottom = 0. ,top = 1. ,left = 0. ,right = 1. ,wspace = 0. ,hspace = 0. )
1280
+ for poly in Poly :
1281
+ px = np .array (poly ).T [0 ]/ scalex
1282
+ py = np .array (poly ).T [1 ]/ scaley
1283
+ ax0 .fill (px ,py ,inmask )
1284
+ ax0 .set_xbound (0 ,Nx )
1285
+ ax0 .set_ybound (0 ,Ny )
1286
+ agg = canvas .switch_backends (hcCanvas )
1287
+ agg .draw ()
1288
+ img , (width , height ) = agg .print_to_buffer ()
1289
+ Zimg = np .frombuffer (img , np .uint8 ).reshape ((height , width , 4 ))
1290
+ return Zimg [:,:,0 ]
1291
+
1292
+ def MakeMaskMap (data ,masks ,iLim ,jLim ):
1293
+ '''Makes a mask array from masking parameters that are not determined by
1294
+ image calibration parameters or the image intensities. Thus this uses
1253
1295
mask Frames, Polygons and Lines settings (but not Thresholds, Rings or
1254
1296
Arcs). Used on a rectangular section of an image (must be 1024x1024 or
1255
1297
smaller, as dictated by module polymask) where the size is determined
@@ -1258,33 +1300,35 @@ def MakeMaskMap(data,masks,iLim,jLim,tamp):
1258
1300
:param dict data: GSAS-II image data object (describes the image)
1259
1301
:param list iLim: boundary along x-pixels
1260
1302
:param list jLim: boundary along y-pixels
1261
- :param np.array tamp: all-zero pixel mask array used in Polymask
1262
- :returns: array[nI,nJ] TA: 2-theta, azimuth, 2 geometric corrections
1303
+ :returns: array[nI,nJ] TA: X, Y
1263
1304
'''
1264
- if GSASIIpath .binaryPath :
1265
- import polymask as pm
1266
- else :
1267
- from . import polymask as pm
1268
1305
pixelSize = data ['pixelSize' ]
1269
1306
scalex = pixelSize [0 ]/ 1000.
1270
1307
scaley = pixelSize [1 ]/ 1000.
1271
-
1308
+ frame = []
1309
+ poly = []
1310
+ if iLim [0 ] == jLim [0 ] == 0 :
1311
+ if masks ['Frames' ]:
1312
+ frame = np .abs (polymask (data ,masks ['Frames' ])- 255 ) #turn inner to outer mask
1313
+ if masks ['Polygons' ]:
1314
+ poly = polymask (data ,masks ['Polygons' ])
1315
+ if len (frame ):
1316
+ masks ['Pmask' ] = frame
1317
+ if len (poly ):
1318
+ masks ['Pmask' ] = masks ['Pmask' ]+ poly
1319
+ if len (poly ):
1320
+ masks ['Pmask' ] = poly
1321
+ else :
1322
+ masks ['Pmask' ] = []
1272
1323
tay ,tax = np .mgrid [iLim [0 ]+ 0.5 :iLim [1 ]+ .5 ,jLim [0 ]+ .5 :jLim [1 ]+ .5 ] #bin centers not corners
1273
1324
tax = np .asfarray (tax * scalex ,dtype = np .float32 ).flatten ()
1274
1325
tay = np .asfarray (tay * scaley ,dtype = np .float32 ).flatten ()
1275
1326
nI = iLim [1 ]- iLim [0 ]
1276
1327
nJ = jLim [1 ]- jLim [0 ]
1277
1328
#make position masks here
1278
- frame = masks ['Frames' ]
1279
1329
tam = ma .make_mask_none ((nI * nJ ))
1280
- if frame :
1281
- tam = ma .mask_or (tam ,ma .make_mask (pm .polymask (nI * nJ ,tax ,
1282
- tay ,len (frame ),frame ,tamp )[:nI * nJ ])^ True )
1283
- polygons = masks ['Polygons' ]
1284
- for polygon in polygons :
1285
- if polygon :
1286
- tam = ma .mask_or (tam ,ma .make_mask (pm .polymask (nI * nJ ,tax ,
1287
- tay ,len (polygon ),polygon ,tamp )[:nI * nJ ]))
1330
+ if len (masks ['Pmask' ]):
1331
+ tam = ma .mask_or (tam ,ma .make_mask (masks ['Pmask' ][iLim [0 ]:iLim [1 ],jLim [0 ]:jLim [1 ]].flatten ()))
1288
1332
points = masks ['Points' ]
1289
1333
if len (points ):
1290
1334
for X ,Y ,rsq in points .T :
@@ -1410,15 +1454,14 @@ def MakeUseMask(data,masks,blkSize=128):
1410
1454
nXBlks = (Nx - 1 )// blkSize + 1
1411
1455
nYBlks = (Ny - 1 )// blkSize + 1
1412
1456
useMask = []
1413
- tamp = ma .make_mask_none ((1024 * 1024 )) #NB: this array size used in the fortran polymask module
1414
1457
for iBlk in range (nYBlks ):
1415
1458
iBeg = iBlk * blkSize
1416
1459
iFin = min (iBeg + blkSize ,Ny )
1417
1460
useMaskj = []
1418
1461
for jBlk in range (nXBlks ):
1419
1462
jBeg = jBlk * blkSize
1420
1463
jFin = min (jBeg + blkSize ,Nx )
1421
- mask = MakeMaskMap (data ,Masks ,(iBeg ,iFin ),(jBeg ,jFin ), tamp ) #2-theta & azimuth arrays & create position mask
1464
+ mask = MakeMaskMap (data ,Masks ,(iBeg ,iFin ),(jBeg ,jFin )) #2-theta & azimuth arrays & create position mask
1422
1465
useMaskj .append (mask )
1423
1466
useMask .append (useMaskj )
1424
1467
return useMask
@@ -1471,7 +1514,6 @@ def AzimuthIntegrate(image,data,masks,ringId,blkSize=1024):
1471
1514
Nx ,Ny = data ['size' ]
1472
1515
nXBlks = (Nx - 1 )// blkSize + 1
1473
1516
nYBlks = (Ny - 1 )// blkSize + 1
1474
- tamp = ma .make_mask_none ((1024 * 1024 )) #NB: this array size used in the fortran histogram2d
1475
1517
for iBlk in range (nYBlks ):
1476
1518
iBeg = iBlk * blkSize
1477
1519
iFin = min (iBeg + blkSize ,Ny )
@@ -1481,7 +1523,7 @@ def AzimuthIntegrate(image,data,masks,ringId,blkSize=1024):
1481
1523
TA = Make2ThetaAzimuthMap (data ,(iBeg ,iFin ),(jBeg ,jFin )) #2-theta & azimuth arrays & create position mask (none here)
1482
1524
TA = np .dstack ((ma .getdata (TA [1 ]),ma .getdata (TA [0 ]),ma .getdata (TA [2 ]),ma .getdata (TA [3 ]))) #azimuth, 2-theta, dist, pol
1483
1525
TAr = [i [:,:,0 ] for i in np .dsplit (TA ,4 )] #azimuth, 2-theta, dist**2/d0**2, pol
1484
- tam = MakeMaskMap (data ,AMasks ,(iBeg ,iFin ),(jBeg ,jFin ), tamp )
1526
+ tam = MakeMaskMap (data ,AMasks ,(iBeg ,iFin ),(jBeg ,jFin ))
1485
1527
Block = image [iBeg :iFin ,jBeg :jFin ] # image Pixel mask has been applied here
1486
1528
tax ,tay ,taz ,tad = Fill2ThetaAzimuthMap (AMasks ,TAr ,tam ,Block ,ringMask = True ) #applies Ring masks only & returns contents
1487
1529
if data .get ('SampleAbs' ,[0.0 ,'' ])[1 ]:
@@ -1565,7 +1607,6 @@ def ImageIntegrate(image,data,masks,blkSize=128,returnN=False,useTA=None,useMask
1565
1607
nYBlks = (Ny - 1 )// blkSize + 1
1566
1608
tbeg = time .time ()
1567
1609
times = [0 ,0 ,0 ,0 ,0 ]
1568
- tamp = ma .make_mask_none ((1024 * 1024 )) #NB: this array size used in the fortran histogram2d
1569
1610
for iBlk in range (nYBlks ):
1570
1611
iBeg = iBlk * blkSize
1571
1612
iFin = min (iBeg + blkSize ,Ny )
@@ -1587,7 +1628,7 @@ def ImageIntegrate(image,data,masks,blkSize=128,returnN=False,useTA=None,useMask
1587
1628
if useMask :
1588
1629
tam = useMask [iBlk ][jBlk ]
1589
1630
else :
1590
- tam = MakeMaskMap (data ,Masks ,(iBeg ,iFin ),(jBeg ,jFin ), tamp )
1631
+ tam = MakeMaskMap (data ,Masks ,(iBeg ,iFin ),(jBeg ,jFin ))
1591
1632
Block = image [iBeg :iFin ,jBeg :jFin ] # image Pixel mask has been applied here
1592
1633
tax ,tay ,taz ,tad = Fill2ThetaAzimuthMap (Masks ,TAr ,tam ,Block ) #applies remaining masks
1593
1634
times [0 ] += time .time ()- t0 # time mask application
@@ -1886,40 +1927,6 @@ def calc2Peak(values,nxy,pixSize,img):
1886
1927
else :
1887
1928
return None
1888
1929
1889
- # Original version
1890
- # def AutoPixelMask(Image,Masks,Controls,numChans,dlg=None):
1891
- # '''Find "bad" regions on an image and remove them with a pixel mask.
1892
- # This works by masking pixels that are well outside the range of the
1893
- # radial average.
1894
- # Original version from RBVD, takes 1-5 min per image. No longer in use.
1895
- # '''
1896
- # #if GSASIIpath.GetConfigValue('debug'): print('original AutoPixelMask starting')
1897
- # frame = Masks['Frames']
1898
- # tam = ma.make_mask_none(Image.shape)
1899
- # if frame:
1900
- # tam = ma.mask_or(tam,MakeFrameMask(Controls,frame))
1901
- # LUtth = np.array(Controls['IOtth'])
1902
- # dtth = (LUtth[1]-LUtth[0])/numChans
1903
- # esdMul = Masks['SpotMask']['esdMul']
1904
- # prob = 100.*sc.erf(esdMul/np.sqrt(2.))
1905
- # print(' Spots greater than %.2f of band intensity are masked'%prob)
1906
- # mask = ma.make_mask_none(Image.shape)
1907
- # band = ma.array(Image,mask=ma.nomask)
1908
- # TA = Make2ThetaAzimuthMap(Controls,(0,Image.shape[0]),(0,Image.shape[1]))[0] #2-theta array
1909
- # TThs = np.linspace(LUtth[0],LUtth[1],numChans,False)
1910
- # for it,TTh in enumerate(TThs):
1911
- # band.mask = ma.masked_outside(TA,TTh,TTh+dtth).mask+tam
1912
- # pcmax = np.percentile(band.compressed(),[prob,50.])
1913
- # mband = ma.masked_greater(band,pcmax[0])
1914
- # std = ma.std(mband)
1915
- # anom = ma.masked_greater((band-pcmax[1])/std,esdMul)
1916
- # mask ^= (anom.mask^band.mask)
1917
- # if not dlg is None:
1918
- # GoOn = dlg.Update(it,newmsg='Processed 2-theta rings = %d'%(it))
1919
- # if not GoOn[0]:
1920
- # break
1921
- # return mask
1922
-
1923
1930
def TestFastPixelMask ():
1924
1931
'''Test if the fast (C) version of Auto Pixel Masking is available.
1925
1932
@@ -1969,7 +1976,7 @@ def FastAutoPixelMask(Image, Masks, Controls, numChans, dlg=None):
1969
1976
frame = Masks ['Frames' ]
1970
1977
tam = ma .make_mask_none (Image .shape )
1971
1978
if frame :
1972
- tam = ma .mask_or (tam ,MakeFrameMask ( Controls ,frame ))
1979
+ tam = ma .mask_or (tam ,ma . make_mask ( np . abs ( polymask ( Controls ,frame ) - 255 ) ))
1973
1980
ttmin = float (Masks ['SpotMask' ].get ('SearchMin' ,0.0 ))
1974
1981
ttmax = float (Masks ['SpotMask' ].get ('SearchMax' ,180.0 ))
1975
1982
esdMul = float (Masks ['SpotMask' ]['esdMul' ])
@@ -2036,7 +2043,7 @@ def MAD(args,**kwargs):
2036
2043
frame = Masks ['Frames' ]
2037
2044
tam = ma .make_mask_none (Image .shape )
2038
2045
if frame :
2039
- tam = ma .mask_or (tam ,MakeFrameMask ( Controls ,frame ))
2046
+ tam = ma .mask_or (tam ,ma . make_mask ( np . abs ( polymask ( Controls ,frame ) - 255 ) ))
2040
2047
LUtth = np .array (Controls ['IOtth' ])
2041
2048
dtth = (LUtth [1 ]- LUtth [0 ])/ numChans
2042
2049
esdMul = Masks ['SpotMask' ]['esdMul' ]
0 commit comments