# -*- coding: utf-8 -*-
# models/cylinders.py
"""This model is a special case of the radially isotropic cylinders, where
the cylinders are also slightly tilted out of the plane parallel to the
detector. This out of plane tilt is described using a Gaussian. The
integration over this tilt angle is done over several segments of the Gaussian
PDF, with each segment occupying an equal cumulative probability. The centroid
value used for the integration is the mass-weighted centre.
"""
from __future__ import absolute_import
from builtins import range
import numpy, scipy, scipy.special, scipy.stats
from numpy import pi, zeros, sin, cos, linspace, diff, sinc
from utils.parameter import FitParameter, Parameter
from bases.model import SASModel
# parameters must not be inf
[docs]class CylindersRadiallyIsotropicTilted(SASModel):
r"""Form factor of cylinders *UNFINISHED*
which are radially isotropic (so not spherically isotropic!)
"""
shortName = "Cylinders defined by aspect ratio"
parameters = (
FitParameter("radius", 1.0,
displayName = "Cylinder radius",
valueRange = (0.1, numpy.inf),
activeRange = (0.1, 1e3),
suffix = "nm"),
FitParameter("aspect", 10.0,
displayName = "Aspect ratio L/(2R) of the cylinder",
valueRange = (0.1, numpy.inf),
activeRange = (1, 20),
suffix = "-"),
FitParameter("psiAngle", 0.1,
displayName = "in-plane cylinder rotation",
valueRange = (0.1, 180.1), suffix = "deg."),
FitParameter("psiAngleDivisions", 303.,
displayName = "in-plane angle divisions",
valueRange = (1, numpy.inf), suffix = "-"),
FitParameter("phiDistWidth", 10.0,
displayName = "out-of-plane axis distribution width",
#with 90 degrees fully out-of-plane (parallel to beam):
valueRange = (0.1, 90.1), suffix = "deg."),
FitParameter("phiDistDivisions", 9.,
displayName = "out of plane integration divisions",
valueRange = (1, numpy.inf), suffix = "-"),
)
def __init__(self):
super(CylindersRadiallyIsotropicTilted, self).__init__()
# some presets of parameters to fit
self.radius.setActive(True)
self.aspect.setActive(False) # not expected to vary
self.psiAngle.setActive(False) # keep out for now.
self.psiAngleDivisions.setActive(False) # not expected to vary
self.phiDistWidth.setActive(False) # gaussian width
self.phiDistDivisions.setActive(False) # integration steps
[docs] def volume(self):
v = pi * self.radius()**2 * (2. * self.radius() * self.aspect())
return v
CylindersRadiallyIsotropicTilted.factory()
#if __name__ == "__main__":
# from bases.datafile import PDHFile, AsciiFile
# # FIXME: use SASData.load() instead
# pf = PDHFile("sasfit_gauss2-1-100-1-1.dat")
# model = CylindersRadiallyIsotropicTilted()
# model.radius.setValue(1.)
# model.radius.setActive(False)
# model.aspect.setValue(100.)
# model.aspect.setActive(False)
# model.psiAngle.setValue(1.)
# model.psiAngle.setActive(False)
# model.psiAngleDivisions.setValue(303)
# model.psiAngleDivisions.setActive(False)
# intensity = model.formfactor(pf.data, None).reshape(-1)
# q = pf.data[:, 0]
# oldInt = pf.data[:, 1]
# delta = abs(oldInt - intensity)
# result = numpy.dstack((q, intensity, delta))[0]
# AsciiFile.writeFile("CylindersRadiallyIsotropic.dat", result)
# # call it like this:
# # PYTHONPATH=..:../mcsas/ python brianpauwgui/gaussianchain.py && gnuplot -p -e 'set logscale xy; plot "gauss.dat" using 1:2:3 with errorbars'
# vim: set ts=4 sts=4 sw=4 tw=0: