@@ -97,7 +97,7 @@ def ellipse_axis_length( p ):
9797 down2 = (b * b - a * c )* ( (a - c )* np .sqrt (1 + 4 * b * b / ((a - c )* (a - c )))- (c + a ))
9898 res1 = np .sqrt (up / down1 )
9999 res2 = np .sqrt (up / down2 )
100- return np .array ([ res2 ,res1 ])
100+ return np .array ([ res2 ,res1 , 0.0 ])
101101
102102 xy = np .array (xy )
103103 x = np .asarray (xy .T [0 ])[:,np .newaxis ]
@@ -371,22 +371,23 @@ def ellipseC():
371371 if debug :
372372 theta = npacosd (1. / np .sqrt (1. + (radii [0 ]/ radii [1 ])** 2 ))
373373 print ('hyperbola:' ,theta )
374- return 200. * np . pi
374+ return 720.
375375 apb = radii [1 ]+ radii [0 ]
376376 amb = radii [1 ]- radii [0 ]
377377 return np .pi * apb * (1 + 3 * (amb / apb )** 2 / (10 + np .sqrt (4 - 3 * (amb / apb )** 2 )))
378-
379378 cent ,phi ,radii = ellipse
379+ if radii [1 ] < 0. :
380+ return None
380381 cphi = cosd (phi - 90. ) #convert to major axis rotation
381382 sphi = sind (phi - 90. )
382383 ring = []
383384 C = int (ellipseC ())* mul #ring circumference in mm
384385 azm = []
385386 for i in range (0 ,C ,1 ): #step around ring in 1mm increments
386387 a = 360. * i / C
387- if radii [1 ] <= 0 : #parabola or hyperbola
388- x = radii [1 ] * coshd (a - phi + 90. ) #major axis
389- y = radii [0 ] * sinhd (a - phi + 90. )
388+ if radii [0 ] <= 0 : #parabola or hyperbola
389+ x = - radii [0 ] / cosd (a - phi ) #major axis
390+ y = radii [1 ] * tand (a - phi )
390391 else :
391392 x = radii [1 ]* cosd (a - phi + 90. ) #major axis
392393 y = radii [0 ]* sind (a - phi + 90. )
@@ -412,7 +413,7 @@ def GetEllipse2(tth,dxy,dist,cent,tilt,phi):
412413 radii[0] (b-minor axis) set < 0. for hyperbola
413414
414415 '''
415- radii = [0 ,0 ]
416+ radii = [0 ,0 , 0 ]
416417 stth = sind (tth )
417418 cosb = cosd (tilt )
418419 tanb = tand (tilt )
@@ -427,6 +428,7 @@ def GetEllipse2(tth,dxy,dist,cent,tilt,phi):
427428 vminus = d * (tanb + (1 - tbp )/ (1 + tbp ))* stth / (cosb - stth )
428429 radii [0 ] = np .sqrt ((vplus + vminus )** 2 - (fplus + fminus )** 2 )/ 2. #+minor axis
429430 radii [1 ] = (vplus + vminus )/ 2. #major axis
431+ radii [2 ] = tth #save for ellipse; might be useful
430432 zdis = (fplus - fminus )/ 2.
431433 else : #hyperbola!
432434 f = d * abs (tanb )* stth / (cosb + stth )
@@ -435,10 +437,11 @@ def GetEllipse2(tth,dxy,dist,cent,tilt,phi):
435437 eps = (v - f )/ (delt - v )
436438 radii [0 ] = - eps * (delt - f )/ np .sqrt (eps ** 2 - 1. ) #-minor axis
437439 radii [1 ] = eps * (delt - f )/ (eps ** 2 - 1. ) #major axis
440+ radii [2 ] = tth #save 2-theta for hyperbola
438441 if tilt > 0 :
439442 zdis = f + radii [1 ]* eps
440443 else :
441- zdis = - f
444+ zdis = - f - radii [ 1 ] * eps
442445#NB: zdis is || to major axis & phi is rotation of minor axis
443446#thus shift from beam to ellipse center is [Z*sin(phi),-Z*cos(phi)]
444447 elcent = [cent [0 ]+ zdis * sind (phi ),cent [1 ]- zdis * cosd (phi )]
@@ -457,21 +460,40 @@ def GetEllipse(dsp,data):
457460 dxy = peneCorr (tth ,dep ,dist )
458461 return GetEllipse2 (tth ,dxy ,dist ,cent ,tilt ,phi )
459462
463+ def LinePlaneCollision (planeNormal , planePoint , rayDirection , rayPoint , epsilon = 1e-6 ):
464+
465+ ndotu = planeNormal .dot (rayDirection )
466+ if ndotu < epsilon :
467+ return None
468+ w = rayPoint - planePoint
469+ si = - planeNormal .dot (w ) / ndotu
470+ Psi = w + si * rayDirection + planePoint
471+ return Psi
472+
473+ def GetDetSamAngle (x ,y ,data ):
474+ def costth (xyz ,d0 ):
475+ ''' compute cos of angle between vectors; xyz not normalized, d0 normalized'''
476+ u = xyz / nl .norm (xyz ,axis = - 1 )[:,:,nxs ]
477+ return np .dot (u ,d0 )
478+ #zero detector 2-theta: tested with tilted images - perfect integrations
479+ dx = x - data ['center' ][0 ]
480+ dy = y - data ['center' ][1 ]
481+ tilt = data ['tilt' ]
482+ dist = data ['distance' ]/ npcosd (tilt ) #sample-beam intersection point on detector plane
483+ T = makeMat (tilt ,0 ) #detector tilt matrix
484+ R = makeMat (data ['rotation' ],2 ) #rotation of tilt axis matrix
485+ MN = np .inner (R ,np .inner (R ,T )) #should be detector transformation matrix; why not np.inner(R,T)
486+ d001 = np .array ([0. ,0. ,1. ]) #vector along z (beam direction); normal to untilted detector plane
487+ r001 = np .inner (d001 ,MN ) #should rotate vector same as detector
488+ dxyz0 = np .inner (np .dstack ([dx ,dy ,np .zeros_like (dx )]),MN ) #transform detector pixel x,y by tilt/rotate
489+ dxyz0 += np .array ([0. ,0. ,dist ]) #shift away from sample
490+ ctth0 = costth (dxyz0 ,r001 ) #cos of angle between detector normal & sample-pixel vector
491+ return ctth0
492+
460493def GetDetectorXY (dsp ,azm ,data ):
461494 '''Get detector x,y position from d-spacing (dsp), azimuth (azm,deg)
462495 & image controls dictionary (data) - new version
463496 '''
464-
465- def LinePlaneCollision (planeNormal , planePoint , rayDirection , rayPoint , epsilon = 1e-6 ):
466-
467- ndotu = planeNormal .dot (rayDirection )
468- if ndotu < epsilon :
469- return None
470- w = rayPoint - planePoint
471- si = - planeNormal .dot (w ) / ndotu
472- Psi = w + si * rayDirection + planePoint
473- return Psi
474-
475497 dist = data ['distance' ]/ npcosd (data ['tilt' ]) #sample-beam intersection point on detector plane
476498 cent = data ['center' ]
477499 phi = data ['rotation' ]
@@ -699,7 +721,7 @@ def EdgeFinder(image,data):
699721 return zip (tax ,tay )
700722
701723def CalcRings (G2frame ,ImageZ ,data ,masks ):
702- ''' Not used anywhere? '''
724+ ''' '''
703725 pixelSize = data ['pixelSize' ]
704726 scalex = 1000. / pixelSize [0 ]
705727 scaley = 1000. / pixelSize [1 ]
@@ -730,7 +752,6 @@ def CalcRings(G2frame,ImageZ,data,masks):
730752 else :
731753 absent = ()
732754 HKL = G2lat .sortHKLd (HKL ,True ,False )
733- wave = data ['wavelength' ]
734755 frame = masks ['Frames' ]
735756 tam = ma .make_mask_none (ImageZ .shape )
736757 if frame :
@@ -808,6 +829,7 @@ def ImageRecalibrate(G2frame,ImageZ,data,masks,getRingsOnly=False):
808829 tam = ma .make_mask_none (ImageZ .shape )
809830 if frame :
810831 tam = ma .mask_or (tam ,ma .make_mask (np .abs (polymask (data ,[frame ,])- 255 )))
832+ hyperbola = False
811833 for iH ,H in enumerate (HKL ):
812834 if debug : print (H )
813835 dsp = H [3 ]
@@ -826,11 +848,14 @@ def ImageRecalibrate(G2frame,ImageZ,data,masks,getRingsOnly=False):
826848 continue
827849 else : #no more rings beyond edge of detector
828850 data ['ellipses' ].append ([])
851+ if Ring is None :
852+ hyperbola = True
829853 continue
830854 if not data ['rings' ]:
831855 G2fil .G2Print ('no rings found; try lower Min ring I/Ib' ,mode = 'warn' )
832856 return []
833-
857+ if hyperbola :
858+ print ('Hyperbola found, outer rings not fitted' )
834859 rings = np .concatenate ((data ['rings' ]),axis = 0 )
835860 if getRingsOnly :
836861 return rings ,HKL
@@ -1516,8 +1541,6 @@ def ImageIntegrate(image,data,masks,blkSize=128,returnN=False,useTA=None,useMask
15161541 H1 = LRazm
15171542 if 'SASD' not in data ['type' ]:
15181543 H0 *= np .array (G2pwd .Polarization (data ['PolaVal' ][0 ],H2 [:- 1 ],0. )[0 ])
1519- # if np.abs(data['det2theta']) < 1.0: #small angle approx only; not appropriate for detectors at large 2-theta
1520- # H0 /= np.abs(npcosd(H2[:-1]+data['tilt']-np.abs(data['det2theta'])))**4 #parallax correction (why **4?)
15211544 if 'SASD' in data ['type' ]:
15221545 H0 /= npcosd (H2 [:- 1 ]) #one more for small angle scattering data?
15231546 if data ['Oblique' ][1 ]:
0 commit comments