Codebase list xrayutilities / 8588492
Imported Upstream version 1.0.3 Eugen Wintersberger 10 years ago
15 changed file(s) with 217 addition(s) and 52 deletion(s). Raw diff Collapse all Expand all
0 v1.0.3, 2013-10-25
1
2 * build_doc target for setup.py to help build docs (thanks to F. Picca)
3 * fix python setup.py --help
4 * add PseudoVoigt function in 1D
5 * add Lorentzian peak shape in addition to Gaussian in new function
6 multPeakFit
7 * some minor bug fixes
8
09 v1.0.2, 2013-09-17
110
211 * add documentation source to tarball
00 Metadata-Version: 1.1
11 Name: xrayutilities
2 Version: 1.0.2
2 Version: 1.0.3
33 Summary: package for x-ray diffraction data evaluation
44 Home-page: http://xrayutilities.sourceforge.net
55 Author: Dominik Kriegner
163163
164164 in any web-browser, after the installation is finished.
165165
166 To build the PDF documentation from the sources use sphinx:
167
168 sphinx-build -b latex doc/source doc/latex
169 cd doc/latex; make
166 To build the PDF documentation from the docu-sources use:
167
168 python setup.py build_doc -b latex
169 cd build/sphinx/latex; make
170170
171 or generate a texinfo file using
172
173 sphinx-build -b texinfo doc/source doc/texinfo
174 cd doc/texinfo; make
171 You will need sphinx and pdflatex including latex-recommended, latex-extra
172 and fonts-recommended.
173
174 Or generate a texinfo file using
175
176 python setup.py build_doc -b texinfo
177 cd build/sphinx/texinfo; make
175178
176179
177180 PACKAGING
155155
156156 in any web-browser, after the installation is finished.
157157
158 To build the PDF documentation from the sources use sphinx:
158 To build the PDF documentation from the docu-sources use:
159159
160 sphinx-build -b latex doc/source doc/latex
161 cd doc/latex; make
160 python setup.py build_doc -b latex
161 cd build/sphinx/latex; make
162162
163 or generate a texinfo file using
163 You will need sphinx and pdflatex including latex-recommended, latex-extra
164 and fonts-recommended.
164165
165 sphinx-build -b texinfo doc/source doc/texinfo
166 cd doc/texinfo; make
166 Or generate a texinfo file using
167
168 python setup.py build_doc -b texinfo
169 cd build/sphinx/texinfo; make
167170
168171
169172 PACKAGING
4949 # The short X.Y version.
5050 version = '1.0'
5151 # The full version, including alpha/beta/rc tags.
52 release = '1.0.2'
52 release = '1.0.3'
5353
5454 # The language for content autogenerated by Sphinx. Refer to documentation
5555 # for a list of supported languages.
380380 :linenos:
381381 :language: python
382382
383 A possible output of this script could be
384
385 .. code-block:: python
386
387 fitted parameters: epsilon: 8.0712e-08 (2,['Parameter convergence'])
388 param: (cch1,cch2,pwidth1,pwidth2,tiltazimuth,tilt,detrot,outerangle_offset)
389 param: 140.07 998.34 4.4545e-05 4.4996e-05 72.0 1.97 -0.792 -1.543
390 please check the resulting data (consider setting plot=True)
391 detector rotation axis / primary beam direction (given by user): ['z+', 'y-'] / x+
392 detector pixel directions / distance: z- y+ / 1
393 detector initialization with: init_area('z-','y+',cch1=140.07,cch2=998.34,Nch1=516,Nch2=516, pwidth1=4.4545e-05,pwidth2=4.4996e-05,distance=1.,detrot=-0.792,tiltazimuth=72.0,tilt=1.543)
394 AND ALWAYS USE an (additional) OFFSET of -1.9741deg in the OUTER DETECTOR ANGLE!
395
396
397 The output gives the fitted detector parameters and compiles the python code line one needs to use to initialize the detector.
398 Important to note is that the outer angle offset which was determined by the fit (-1.9741 degree in the aboves example) is not included in the initialization of the detector parameters BUT needs to be used in every call to the q-conversion function as offset.
399 This step needs to be performed manually by the user!
400
383401 Area detector (Variant 2)
384402 ^^^^^^^^^^^^^^^^^^^^^^^^^
385403
doc/xrayutilities.info less more
Binary diff not shown
3131
3232 print("angles: 0,0,0,90")
3333 (qx,qy,qz) = qconv(0,0,0,90)
34 print("Q= %6.3f %6.3f %6.3f (Abs: %6.3f)" %(qx[0],qy[0],qz[0],numpy.linalg.norm((qx,qy,qz))))
34 print("Q= %6.3f %6.3f %6.3f (Abs: %6.3f)" %(qx,qy,qz,numpy.linalg.norm((qx,qy,qz))))
3535
3636 print("angles: 90,0,0,90")
3737 (qx,qy,qz) = qconv(90,0,0,90)
38 print("Q= %6.3f %6.3f %6.3f (Abs: %6.3f)" %(qx[0],qy[0],qz[0],numpy.linalg.norm((qx,qy,qz))))
38 print("Q= %6.3f %6.3f %6.3f (Abs: %6.3f)" %(qx,qy,qz,numpy.linalg.norm((qx,qy,qz))))
3939
4040 print("angles: 0,90,0,90")
4141 (qx,qy,qz) = qconv(0,90,0,90)
42 print("Q= %6.3f %6.3f %6.3f (Abs: %6.3f)" %(qx[0],qy[0],qz[0],numpy.linalg.norm((qx,qy,qz))))
42 print("Q= %6.3f %6.3f %6.3f (Abs: %6.3f)" %(qx,qy,qz,numpy.linalg.norm((qx,qy,qz))))
4343
2020 from distutils.fancy_getopt import FancyGetopt
2121 import os.path
2222 import numpy
23 import sys
2324
2425 cliopts = []
2526 cliopts.append(("without-openmp",None,"build without OpenMP support"))
2627
2728 options = FancyGetopt(option_table = cliopts)
28 args,opts = options.getopt()
29
30 #first read all the arguments passed to the script
31 #we need to do this otherwise the --help commands would not work
32 args = sys.argv[1:]
33 try:
34 #search the arguments for options we would like to use
35 #get new args with the custom options stripped away
36 args,opts = options.getopt(args)
37 except:
38 pass
2939
3040 #set default flags
3141 without_openmp = False
6373 e.extra_link_args = lopt[ c ]
6474 build_ext.build_extensions(self)
6575
76 cmdclass = {'build_ext': build_ext_subclass}
77
6678 with open('README.txt') as f:
6779 long_description = f.read()
6880
7587 os.path.join('xrayutilities','src','gridder3d.c')],
7688 define_macros = user_macros)
7789
90 try:
91 import sphinx
92 from sphinx.setup_command import BuildDoc
93
94 class build_doc(BuildDoc):
95 def run(self):
96 # make sure the python path is pointing to the newly built
97 # code so that the documentation is built on this and not a
98 # previously installed version
99 build = self.get_finalized_command('build')
100 sys.path.insert(0, os.path.abspath(build.build_lib))
101 try:
102 sphinx.setup_command.BuildDoc.run(self)
103 except UnicodeDecodeError:
104 print("ERROR: unable to build documentation"
105 " because Sphinx do not handle"
106 " source path with non-ASCII characters. Please"
107 " try to move the source package to another"
108 " location (path with *only* ASCII characters)")
109 sys.path.pop(0)
110
111 cmdclass['build_doc'] = build_doc
112 except ImportError:
113 pass
114
78115 setup(name="xrayutilities",
79 version="1.0.2",
116 version="1.0.3",
80117 author="Eugen Wintersberger, Dominik Kriegner",
81118 description="package for x-ray diffraction data evaluation",
82119 classifiers=["Topic :: Scientific/Engineering :: Physics",
95132 requires=['numpy','scipy','matplotlib','tables'],
96133 include_dirs = [numpy.get_include()],
97134 ext_modules = [extmodul],
98 cmdclass = {'build_ext': build_ext_subclass },
135 cmdclass = cmdclass,
99136 url="http://xrayutilities.sourceforge.net",
100137 license="GPLv2",
101138 script_args = args
1818
1919 from .. import config
2020 from .. import experiment
21 from .. import gridder as xugridder
21 from .. import gridder3d as xugridder
2222
2323 def getindex3d(x,y,z,xgrid,ygrid,zgrid):
2424 """
17741774 else:
17751775 [qx,qy,qz] = exphxrd.Ang2Q(om,tt)
17761776 [qxsub,qysub,qzsub] = exphxrd.Ang2Q(omalign,ttalign)
1777 params = [qysub[0],qzsub[0],0.001,0.001,psd.max(),0,0.]
1778 params,covariance = math.fit_peak2d(qy.flatten(),qz.flatten(),psd.flatten(),params,[qysub[0]-frange[0],qysub[0]+frange[0],qzsub[0]-frange[1],qzsub[0]+frange[1]],math.Gauss2d,maxfev=10000)
1777 params = [qysub,qzsub,0.001,0.001,psd.max(),0,0.]
1778 params,covariance = math.fit_peak2d(qy.flatten(),qz.flatten(),psd.flatten(),params,[qysub-frange[0],qysub+frange[0],qzsub-frange[1],qzsub+frange[1]],math.Gauss2d,maxfev=10000)
17791779 # correct params
17801780 params[6] = params[6]%(numpy.pi)
17811781 if params[5]<0 : params[5] = 0
17861786
17871787 if plot:
17881788 plt.figure(); plt.clf()
1789 from .. import gridder
1789 from ..gridder2d import Gridder2D
17901790 from .. import utilities
1791 gridder = gridder.Gridder2D(400,400)
1791 gridder = Gridder2D(400,400)
17921792 gridder(qy,qz,psd)
17931793 # calculate intensity which should be plotted
17941794 INT = utilities.maplog(gridder.gdata.transpose(),4,0)
11251125 raise Exception("unknown keyword argument given: allowed are 'B': orthonormalization matrix, 'U': orientation matrix, 'mat': material object, 'dettype': string with detector type")
11261126
11271127 if "B" in kwargs:
1128 B = numpy.array(B)
1128 B = numpy.array(kwargs['B'])
11291129 kwargs.pop("B")
11301130 elif "mat" in kwargs:
11311131 mat = kwargs['mat']
11351135 B = numpy.identity(3)
11361136
11371137 if "U" in kwargs:
1138 U = numpy.array(U)
1138 U = numpy.array(kwargs['U'])
11391139 kwargs.pop("U")
11401140 else:
11411141 U = self._transform.matrix
4242 from .functions import Gauss3d
4343 from .functions import TwoGauss2d
4444 from .functions import Lorentz1d
45 from .functions import Lorentz1d_der_x
46 from .functions import Lorentz1d_der_p
4547 from .functions import Lorentz2d
48 from .functions import PseudoVoigt1d
4649
4750 from .fit import fit_peak2d
4851 from .fit import gauss_fit
52 from .fit import multPeakFit
53 from .fit import multPeakPlot
4954 from .fit import multGaussFit
5055 from .fit import multGaussPlot
2828
2929 from .. import config
3030 from .functions import Gauss1d,Gauss1d_der_x,Gauss1d_der_p
31 from .functions import Lorentz1d,Lorentz1d_der_x,Lorentz1d_der_p
3132
3233 try:
3334 from matplotlib import pyplot as plt
8384 # use least-square fit
8485 myodr.set_job(fit_type=2)
8586
86 # # DK comment out because this command triggers a synthax error with new scipy version 2013/5/7
87 # # DK commented out because this command triggers a synthax error with new scipy version 2013/5/7
8788 # if config.VERBOSITY >= config.DEBUG:
8889 # myodr.set_iprint(final=1)
8990
156157 return p,pcov
157158
158159
159 def multGaussFit(x,data,peakpos,peakwidth,dranges=None):
160 """
161 function to fit multiple Gaussian peaks with linear background to a set of data
160 def multGaussFit(*args,**kwargs):
161 """
162 convenience function to keep API stable
163 see multPeakFit for documentation
164 """
165 kwargs['peaktype']='Gaussian'
166 return multPeakFit(*args,**kwargs)
167
168 def multPeakFit(x,data,peakpos,peakwidth,dranges=None,peaktype='Gaussian'):
169 """
170 function to fit multiple Gaussian/Lorentzian peaks with linear background to a set of data
162171
163172 Parameters
164173 ----------
168177 peakwidth: initial values for the peak width
169178 dranges: list of tuples with (min,max) value of the data ranges to use.
170179 does not need to have the same number of entries as peakpos
180 peaktype: type of peaks to be used: can be either 'Gaussian' or 'Lorentzian'
171181
172182 Returns
173183 -------
178188 amp: list of amplitudes of the peaks derived by the fit
179189 background: array of background values at positions x
180190 """
191 if peaktype=='Gaussian':
192 pfunc = Gauss1d
193 pfunc_derx = Gauss1d_der_x
194 elif peaktype=='Lorentzian':
195 pfunc = Lorentz1d
196 pfunc_derx = Lorentz1d_der_x
197 else:
198 raise ValueError('wrong value for parameter peaktype was given')
199
181200 def deriv_x(p, x):
182201 """
183202 function to calculate the derivative of the signal of multiple peaks and background w.r.t. the x-coordinate
190209
191210 # sum up peak functions contributions
192211 for i in range(len(p)//3):
193 ldx = Gauss1d_der_x(x,p[3*i],p[3*i+1],p[3*i+2],0)
212 ldx = pfunc_derx(x,p[3*i],p[3*i+1],p[3*i+2],0)
194213 derx += ldx
195214
196215 # background contribution
214233 # peak functions contributions
215234 for i in range(len(p)//3):
216235 lp = (p[3*i],p[3*i+1],p[3*i+2],0)
217 derp = numpy.append(derp,-2*(lp[0]-x)*Gauss1d(x,*lp))
218 derp = numpy.append(derp,(lp[0]-x)**2/(2*lp[1]**3)*Gauss1d(x,*lp))
219 derp = numpy.append(derp,Gauss1d(x,*lp)/lp[2])
220
236 if peaktype == 'Gaussian':
237 derp = numpy.append(derp,-2*(lp[0]-x)*pfunc(x,*lp))
238 derp = numpy.append(derp,(lp[0]-x)**2/(2*lp[1]**3)*pfunc(x,*lp))
239 derp = numpy.append(derp,pfunc(x,*lp)/lp[2])
240 else: # Lorentzian
241 derp = numpy.append(derp,4*(x-lp[0])* lp[2]/lp[1]/(1+(2*(x-lp[0])/lp[1])**2)**2)
242 derp = numpy.append(derp,4*(lp[0]-x)* lp[2]/lp[1]**2/(1+(2*(x-lp[0])/lp[1])**2)**2)
243 derp = numpy.append(derp,1/(1+(2*(x-p[0])/p[1])**2))
244
221245 # background contributions
222246 derp = numpy.append(derp,x)
223247 derp = numpy.append(derp,numpy.ones(x.size))
238262
239263 # sum up peak functions
240264 for i in range(len(p)//3):
241 lf = Gauss1d(x,p[3*i],p[3*i+1],p[3*i+2],0)
265 lf = pfunc(x,p[3*i],p[3*i+1],p[3*i+2],0)
242266 f += lf
243267
244268 # background
290314 fit = my_odr.run()
291315
292316 if(config.VERBOSITY >= config.DEBUG):
293 print("XU.math.multGaussFit: fitted parameters")
317 print("XU.math.multPeakFit: fitted parameters")
294318 print(fit.beta)
295319 try:
296320 if fit.stopreason[0] not in ['Sum of squares convergence']:
297 print("XU.math.multGaussFit: fit NOT converged (%s)" %fit.stopreason[0])
321 print("XU.math.multPeakFit: fit NOT converged (%s)" %fit.stopreason[0])
298322 return None,None,None,None
299323 except:
300 print("XU.math.multGaussFit: fit most probably NOT converged (%s)" %str(fit.stopreason))
324 print("XU.math.multPeakFit: fit most probably NOT converged (%s)" %str(fit.stopreason))
301325 return None,None,None,None
302326 # prepare return values
303327 fpos = fit.beta[:-2:3]
307331
308332 return fpos,fwidth,famp,background
309333
310 def multGaussPlot(x,fpos,fwidth,famp,background,dranges=None,fig="xu_plot",fact=1.):
311 """
312 function to plot multiple Gaussian peaks with linear background
334
335 def multGaussPlot(*args,**kwargs):
336 """
337 convenience function to keep API stable
338 see multPeakPlot for documentation
339 """
340 kwargs['peaktype']='Gaussian'
341 return multPeakPlot(*args,**kwargs)
342
343 def multPeakPlot(x,fpos,fwidth,famp,background,dranges=None,peaktype='Gaussian',fig="xu_plot",fact=1.):
344 """
345 function to plot multiple Gaussian/Lorentz peaks with background values given by an array
313346
314347 Parameters
315348 ----------
320353 background: array with background values
321354 dranges: list of tuples with (min,max) value of the data ranges to use.
322355 does not need to have the same number of entries as fpos
356 peaktype: type of peaks to be used: can be either 'Gaussian' or 'Lorentzian'
323357 fig: matplotlib figure number or name
324358 fact: factor to use as multiplicator in the plot
325359 """
326360
327361 try: plt.__name__
328362 except NameError:
329 print("XU.math.multGaussPlot: Warning: plot functionality not available")
363 print("XU.math.multPeakPlot: Warning: plot functionality not available")
330364 return
331365
332366 plt.figure(fig)
345379
346380 f = numpy.zeros(lx.size)
347381 for i in range(len(fpos)):
348 lf = Gauss1d(lx,fpos[i],fwidth[i],famp[i],0)
382 if peaktype=='Gaussian':
383 lf = Gauss1d(lx,fpos[i],fwidth[i],famp[i],0)
384 elif peaktype=='Lorentzian':
385 lf = Lorentz1d(lx,fpos[i],fwidth[i],famp[i],0)
386 else:
387 raise ValueError('wrong value for parameter peaktype was given')
349388 f += lf
350389 plt.plot(lx,(lf+lb)*fact,'k:')
351390
110110 for parameter description see Gauss1d
111111 """
112112
113 return 2*(p[0]-x)*Gauss1d(x,*p)
113 lp = numpy.copy(p)
114 lp[3] = 0
115 return 2*(p[0]-x)*Gauss1d(x,*lp)
114116
115117
116118 def Gauss1d_der_p(x,*p):
120122
121123 for parameter description see Gauss1d
122124 """
123
124 r = numpy.concatenate(( -2*(p[0]-x)*Gauss1d(x,*p),\
125 (p[0]-x)**2/(2*p[1]**3)*Gauss1d(x,*p),\
126 Gauss1d(x,*p)/p[2],\
125 lp = numpy.copy(p)
126 lp[3] = 0
127 r = numpy.concatenate(( -2*(p[0]-x)*Gauss1d(x,*lp),\
128 (p[0]-x)**2/(2*p[1]**3)*Gauss1d(x,*lp),\
129 Gauss1d(x,*lp)/p[2],\
127130 numpy.ones(x.shape,dtype=numpy.float) ))
128131 r.shape = (4,) + x.shape
129132
224227
225228 return g
226229
230 def Lorentz1d_der_x(x,*p):
231 """
232 function to calculate the derivative of a Gaussian with respect to x
233
234 for parameter description see Lorentz1d
235 """
236
237 return 4*(p[0]-x)* p[2]/p[1]/(1+(2*(x-p[0])/p[1])**2)**2
238
239 def Lorentz1d_der_p(x,*p):
240 """
241 function to calculate the derivative of a Gaussian with respect the
242 parameters p
243
244 for parameter description see Lorentz1d
245 """
246
247 r = numpy.concatenate(( 4*(x-p[0])* p[2]/p[1]/(1+(2*(x-p[0])/p[1])**2)**2,\
248 4*(p[0]-x)* p[2]/p[1]**2/(1+(2*(x-p[0])/p[1])**2)**2,\
249 1/(1+(2*(x-p[0])/p[1])**2),\
250 numpy.ones(x.shape,dtype=numpy.float) ))
251 r.shape = (4,) + x.shape
252
253 return r
254
227255 def Lorentz2d(x,y,*p):
228256 """
229257 function to calculate a general two dimensional Lorentzian
248276
249277 g = p[5]+p[4]/(1+(2*(rcen_x-xp)/p[2])**2+(2*(rcen_y-yp)/p[3])**2)
250278 return g
279
280
281 def PseudoVoigt1d(x,*p):
282 """
283 function to calculate a pseudo Voigt function as linear combination of a Gauss and Lorentz peak
284
285 Parameters
286 ----------
287 p: list of parameters of the Lorentz-function
288 [XCEN,FWHM,AMP,BACKGROUND,ETA]
289 ETA: 0 ...1 0 means pure Gauss and 1 means pure Lorentz
290 x,y: coordinate(s) where the function should be evaluated
291
292 Returns
293 -------
294 the value of the PseudoVoigt described by the parameters p
295 at position (x,y)
296
297 """
298
299 f = p[3]+p[2] * ( p[4]*(1/(1+(2*(x-p[0])/(p[1]/2.))**2)) + (1-p[4])*numpy.exp(-numpy.log(2)*((p[0]-x)/(p[1]/2.))**2) )
300
301 return f
251302
252303
253304 def Debye1(x):
Binary diff not shown