@@ -788,50 +788,50 @@ def EdgeFinder(image,data):
788788 tax = ma .compressed (ma .array (tax .flatten (),mask = tam ))
789789 tay = ma .compressed (ma .array (tay .flatten (),mask = tam ))
790790 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
835835
836836def CalcRings (G2frame ,ImageZ ,data ,masks ):
837837 pixelSize = data ['pixelSize' ]
@@ -868,7 +868,7 @@ def CalcRings(G2frame,ImageZ,data,masks):
868868 frame = masks ['Frames' ]
869869 tam = ma .make_mask_none (ImageZ .shape )
870870 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 ) ))
872872 for iH ,H in enumerate (HKL ):
873873 if debug : print (H )
874874 dsp = H [3 ]
@@ -946,7 +946,7 @@ def ImageRecalibrate(G2frame,ImageZ,data,masks,getRingsOnly=False):
946946 frame = masks ['Frames' ]
947947 tam = ma .make_mask_none (ImageZ .shape )
948948 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 ) ))
950950 for iH ,H in enumerate (HKL ):
951951 if debug : print (H )
952952 dsp = H [3 ]
@@ -1247,9 +1247,51 @@ def Make2ThetaAzimuthMap(data,iLim,jLim): #most expensive part of integration!
12471247 TA [3 ] = G2pwd .Polarization (data ['PolaVal' ][0 ],TA [0 ],TA [1 ]- 90. )[0 ]
12481248 return TA #2-theta, azimuth & geom. corr. arrays
12491249
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
12531295 mask Frames, Polygons and Lines settings (but not Thresholds, Rings or
12541296 Arcs). Used on a rectangular section of an image (must be 1024x1024 or
12551297 smaller, as dictated by module polymask) where the size is determined
@@ -1258,33 +1300,35 @@ def MakeMaskMap(data,masks,iLim,jLim,tamp):
12581300 :param dict data: GSAS-II image data object (describes the image)
12591301 :param list iLim: boundary along x-pixels
12601302 :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
12631304 '''
1264- if GSASIIpath .binaryPath :
1265- import polymask as pm
1266- else :
1267- from . import polymask as pm
12681305 pixelSize = data ['pixelSize' ]
12691306 scalex = pixelSize [0 ]/ 1000.
12701307 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' ] = []
12721323 tay ,tax = np .mgrid [iLim [0 ]+ 0.5 :iLim [1 ]+ .5 ,jLim [0 ]+ .5 :jLim [1 ]+ .5 ] #bin centers not corners
12731324 tax = np .asfarray (tax * scalex ,dtype = np .float32 ).flatten ()
12741325 tay = np .asfarray (tay * scaley ,dtype = np .float32 ).flatten ()
12751326 nI = iLim [1 ]- iLim [0 ]
12761327 nJ = jLim [1 ]- jLim [0 ]
12771328 #make position masks here
1278- frame = masks ['Frames' ]
12791329 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 ()))
12881332 points = masks ['Points' ]
12891333 if len (points ):
12901334 for X ,Y ,rsq in points .T :
@@ -1410,15 +1454,14 @@ def MakeUseMask(data,masks,blkSize=128):
14101454 nXBlks = (Nx - 1 )// blkSize + 1
14111455 nYBlks = (Ny - 1 )// blkSize + 1
14121456 useMask = []
1413- tamp = ma .make_mask_none ((1024 * 1024 )) #NB: this array size used in the fortran polymask module
14141457 for iBlk in range (nYBlks ):
14151458 iBeg = iBlk * blkSize
14161459 iFin = min (iBeg + blkSize ,Ny )
14171460 useMaskj = []
14181461 for jBlk in range (nXBlks ):
14191462 jBeg = jBlk * blkSize
14201463 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
14221465 useMaskj .append (mask )
14231466 useMask .append (useMaskj )
14241467 return useMask
@@ -1471,7 +1514,6 @@ def AzimuthIntegrate(image,data,masks,ringId,blkSize=1024):
14711514 Nx ,Ny = data ['size' ]
14721515 nXBlks = (Nx - 1 )// blkSize + 1
14731516 nYBlks = (Ny - 1 )// blkSize + 1
1474- tamp = ma .make_mask_none ((1024 * 1024 )) #NB: this array size used in the fortran histogram2d
14751517 for iBlk in range (nYBlks ):
14761518 iBeg = iBlk * blkSize
14771519 iFin = min (iBeg + blkSize ,Ny )
@@ -1481,7 +1523,7 @@ def AzimuthIntegrate(image,data,masks,ringId,blkSize=1024):
14811523 TA = Make2ThetaAzimuthMap (data ,(iBeg ,iFin ),(jBeg ,jFin )) #2-theta & azimuth arrays & create position mask (none here)
14821524 TA = np .dstack ((ma .getdata (TA [1 ]),ma .getdata (TA [0 ]),ma .getdata (TA [2 ]),ma .getdata (TA [3 ]))) #azimuth, 2-theta, dist, pol
14831525 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 ))
14851527 Block = image [iBeg :iFin ,jBeg :jFin ] # image Pixel mask has been applied here
14861528 tax ,tay ,taz ,tad = Fill2ThetaAzimuthMap (AMasks ,TAr ,tam ,Block ,ringMask = True ) #applies Ring masks only & returns contents
14871529 if data .get ('SampleAbs' ,[0.0 ,'' ])[1 ]:
@@ -1565,7 +1607,6 @@ def ImageIntegrate(image,data,masks,blkSize=128,returnN=False,useTA=None,useMask
15651607 nYBlks = (Ny - 1 )// blkSize + 1
15661608 tbeg = time .time ()
15671609 times = [0 ,0 ,0 ,0 ,0 ]
1568- tamp = ma .make_mask_none ((1024 * 1024 )) #NB: this array size used in the fortran histogram2d
15691610 for iBlk in range (nYBlks ):
15701611 iBeg = iBlk * blkSize
15711612 iFin = min (iBeg + blkSize ,Ny )
@@ -1587,7 +1628,7 @@ def ImageIntegrate(image,data,masks,blkSize=128,returnN=False,useTA=None,useMask
15871628 if useMask :
15881629 tam = useMask [iBlk ][jBlk ]
15891630 else :
1590- tam = MakeMaskMap (data ,Masks ,(iBeg ,iFin ),(jBeg ,jFin ), tamp )
1631+ tam = MakeMaskMap (data ,Masks ,(iBeg ,iFin ),(jBeg ,jFin ))
15911632 Block = image [iBeg :iFin ,jBeg :jFin ] # image Pixel mask has been applied here
15921633 tax ,tay ,taz ,tad = Fill2ThetaAzimuthMap (Masks ,TAr ,tam ,Block ) #applies remaining masks
15931634 times [0 ] += time .time ()- t0 # time mask application
@@ -1886,40 +1927,6 @@ def calc2Peak(values,nxy,pixSize,img):
18861927 else :
18871928 return None
18881929
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-
19231930def TestFastPixelMask ():
19241931 '''Test if the fast (C) version of Auto Pixel Masking is available.
19251932
@@ -1969,7 +1976,7 @@ def FastAutoPixelMask(Image, Masks, Controls, numChans, dlg=None):
19691976 frame = Masks ['Frames' ]
19701977 tam = ma .make_mask_none (Image .shape )
19711978 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 ) ))
19731980 ttmin = float (Masks ['SpotMask' ].get ('SearchMin' ,0.0 ))
19741981 ttmax = float (Masks ['SpotMask' ].get ('SearchMax' ,180.0 ))
19751982 esdMul = float (Masks ['SpotMask' ]['esdMul' ])
@@ -2036,7 +2043,7 @@ def MAD(args,**kwargs):
20362043 frame = Masks ['Frames' ]
20372044 tam = ma .make_mask_none (Image .shape )
20382045 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 ) ))
20402047 LUtth = np .array (Controls ['IOtth' ])
20412048 dtth = (LUtth [1 ]- LUtth [0 ])/ numChans
20422049 esdMul = Masks ['SpotMask' ]['esdMul' ]
0 commit comments