Vous avez reçu un message "Your GitLab account has been locked ..." ? Pas d'inquiétude : lisez cet article https://docs.gricad-pages.univ-grenoble-alpes.fr/help/unlock/

Commit f5ba271f authored by Edward Andò's avatar Edward Andò
Browse files

spaces, and checks into asserts

parent 0fe7d6f7
Pipeline #72151 passed with stages
in 13 minutes and 40 seconds
......@@ -80,9 +80,8 @@ def fitVonMisesFisher(orientations, confVMF=None, confMu=None, confKappa=None):
"""
# Check that the vectors are 3D
if orientations.shape[1] != 3:
print('\n spam.orientations.fitVonMisesFisher: The vectors must be an array of Nx3')
return
assert orientations.shape[1] == 3, '\n spam.orientations.fitVonMisesFisher: The vectors must be an array of Nx3'
# If needed, assign confidence intervals
if confVMF is None:
confVMF = 0.95
......@@ -91,15 +90,10 @@ def fitVonMisesFisher(orientations, confVMF=None, confMu=None, confKappa=None):
if confKappa is None:
confKappa = 0.95
# Check the values of the confidence intervals
if confVMF < 0 or confVMF > 1:
print('\n spam.orientations.fitVonMisesFisher: The confidence interval for confVMF should be between 0 and 1')
return
if confMu < 0 or confMu > 1:
print('\n spam.orientations.fitVonMisesFisher: The confidence interval for confMu should be between 0 and 1')
return
if confKappa < 0 or confKappa > 1:
print('\n spam.orientations.fitVonMisesFisher: The confidence interval for confKappa should be between 0 and 1')
return
assert confVMF > 0 and confVMF < 1, '\n spam.orientations.fitVonMisesFisher: The confidence interval for confVMF should be between 0 and 1'
assert confMu > 0 and confMu < 1, '\n spam.orientations.fitVonMisesFisher: The confidence interval for confMu should be between 0 and 1'
assert confKappa > 0 and confKappa < 1, '\n spam.orientations.fitVonMisesFisher: The confidence interval for confKappa should be between 0 and 1'
# Create result dictionary
res = {}
# Remove possible vectors [0, 0, 0]
......@@ -289,11 +283,11 @@ def projectOrientation(vector, coordSystem, projectionSystem):
Vector to be projected
For cartesian system: ZYX
For spherical system: r, tetha (inclination), phi (azimuth) in Radians
coordSystem: string
Coordinate system of the vector
Either "cartesian" or "spherical"
projectionSystem : string
Projection to be used
Either "lambert", "stereo" or "equidistant"
......@@ -307,20 +301,20 @@ def projectOrientation(vector, coordSystem, projectionSystem):
Theta and R coordinates of the projected vector in radians
"""
projection_xy_local = numpy.zeros( (2) )
projection_theta_r_local = numpy.zeros( (2) )
# Reshape the vector and check for errors in shape
try:
vector = numpy.reshape(vector, (3,1))
except:
print('\n spam.orientations.projectOrientation: The vector must be an array of 1x3')
return
if coordSystem == "spherical":
# unpack vector
r, theta, phi = vector
x = r * math.sin( theta ) * math.cos( phi )
......@@ -328,7 +322,7 @@ def projectOrientation(vector, coordSystem, projectionSystem):
z = r * math.cos( theta )
elif coordSystem == "cartesian":
# unpack vector
z, y, x = vector
# we're in cartesian coordinates, (x-y-z mode) Calculate spherical coordinates
......@@ -339,7 +333,7 @@ def projectOrientation(vector, coordSystem, projectionSystem):
r = numpy.sqrt( x**2 + y**2 + z**2 )
theta = math.acos( z / r ) # inclination
phi = math.atan2( y, x ) # azimuth
else:
print('\n spam.orientations.projectOrientation: Wrong coordinate system')
return
......@@ -376,10 +370,10 @@ def projectOrientation(vector, coordSystem, projectionSystem):
projection_theta_r_local[0] = phi
projection_theta_r_local[1] = numpy.cos( theta - math.pi/2 )
else:
print('\n spam.orientations.projectOrientation: Wrong projection system')
return
return projection_xy_local, projection_theta_r_local
......@@ -21,30 +21,25 @@ def generateIsotropic(N):
Note
----------
For references, see
For references, see:
http://www.cgafaq.info/wiki/Evenly_distributed_points_on_sphere
Which in turn was based on
Which in turn was based on:
http://sitemason.vanderbilt.edu/page/hmbADS
From
From:
Rakhmanov, Saff and Zhou: **Minimal Discrete Energy on the Sphere**, Mathematical Research Letters, Vol. 1 (1994), pp. 647-662:
https://www.math.vanderbilt.edu/~esaff/texts/155.pdf
Also see discussion here
Also see discussion here:
http://groups.google.com/group/sci.math/browse_thread/thread/983105fb1ced42c/e803d9e3e9ba3d23#e803d9e3e9ba3d23%22%22
"""
# Chech that it is an integer
if not isinstance(N,int):
print('\n spam.orientations.generateIsotropic: Number of vectors should be an integer')
return
# Check that it is an integer
assert isinstance(N,int), '\n spam.orientations.generateIsotropic: Number of vectors should be an integer'
# Check value of number of vectors
if N <=0:
print('\n spam.orientations.generateIsotropic: Number of vectors should be > 0')
return
assert N > 0, '\n spam.orientations.generateIsotropic: Number of vectors should be > 0'
M = int(N)*2
s = 3.6 / math.sqrt(M)
......@@ -93,13 +88,8 @@ def generateIcosphere(subDiv):
From: https://sinestesia.co/blog/tutorials/python-icospheres/
"""
# Chech that it is an integer
if not isinstance(subDiv,int):
print('\n spam.orientations.generateIcosphere: Number of subDiv should be an integer')
return
# Check value of number of subDiv
if subDiv <=0:
print('\n spam.orientations.generateIcosphere: Number of subDiv should be > 0')
return
assert isinstance(subDiv,int), '\n spam.orientations.generateIcosphere: Number of subDiv should be an integer'
assert subDiv > 0, print('\n spam.orientations.generateIcosphere: Number of subDiv should be > 0')
# 1. Internal functions
......@@ -236,7 +226,6 @@ def generateVonMisesFisher(mu, kappa, N=1):
"""
def randUniformCircle(N):
# N number of orientations
v = numpy.random.normal(0,1,(N,2))
......@@ -267,18 +256,10 @@ def generateVonMisesFisher(mu, kappa, N=1):
return orientations
# Check for non-scalar value of kappa
if not numpy.isscalar(kappa):
print('\n spam.orientations.generateVonMisesFisher: kappa should a scalar')
return
# Check value of kappa
if kappa <=0:
print('\n spam.orientations.generateVonMisesFisher: kappa should be > 0')
return
# Check value of N
if N <=1:
print('\n spam.orientations.generateVonMisesFisher: The number of vectors should be > 1')
return
# Reshape mu and check for errors in shape
assert numpy.isscalar(kappa), '\n spam.orientations.generateVonMisesFisher: kappa should a scalar'
assert kappa > 0, '\n spam.orientations.generateVonMisesFisher: kappa should be > 0'
assert N > 1, '\n spam.orientations.generateVonMisesFisher: The number of vectors should be > 1'
try:
mu = numpy.reshape( mu, (1,3))
except:
......@@ -301,5 +282,5 @@ def generateVonMisesFisher(mu, kappa, N=1):
O = scipy.linalg.null_space(mu)
R = numpy.concatenate((mu.T,O),axis=1)
orientations = numpy.dot(R,orientations.T).T
return orientations
......@@ -4,13 +4,15 @@ from __future__ import print_function
import unittest
import numpy, random
import spam.orientations
import pytest
class testAll(unittest.TestCase):
def tearDown(self):
try:
pass
except OSError:
pass
def test_meanOrientation(self):
# Generate random main direction
alpha = random.randrange(30, 330, 1)
......@@ -33,7 +35,7 @@ class testAll(unittest.TestCase):
# Check if the difference between the angles is less than 5 degree
self.assertLess(numpy.abs(thetaSVD - theta), 5)
self.assertLess(numpy.abs(alphaSVD - alpha), 5)
def test_fabricTensor(self):
# Define number of vector
n = 1000
......@@ -58,7 +60,7 @@ class testAll(unittest.TestCase):
NRand, FRand, aRand = spam.orientations.fabricTensor(orientations)
# Test the results
self.assertGreater(aRand, aEq)
def test_projectVector(self):
# 0. Usual test for input data
res = spam.orientations.projectOrientation([0,1], 'cartesian', 'lambert')
......@@ -67,7 +69,7 @@ class testAll(unittest.TestCase):
self.assertEqual(res, None)
res = spam.orientations.projectOrientation([0,1], 'cartesian', 'x')
self.assertEqual(res, None)
# 1. Cartesian coord
# Lambert projection on the edge of the disk
xy, theta = spam.orientations.projectOrientation([0,1,0], 'cartesian', 'lambert')
......@@ -84,7 +86,7 @@ class testAll(unittest.TestCase):
# The radius should be 1
self.assertAlmostEqual(theta[1], 1, places=3)
self.assertAlmostEqual(numpy.sqrt((xy[0])**2 +(xy[1])**2), 1, places=3)
# 2. Spherical coordinates
# Lambert projection on the edge of the disk
xy, theta = spam.orientations.projectOrientation([1,0.5*numpy.pi,numpy.pi], 'spherical', 'lambert')
......@@ -110,12 +112,13 @@ class testAll(unittest.TestCase):
self.assertEqual(orientations, None)
# 2. Check for value of kappa
vect = numpy.array([2,1,1])
orientations = spam.orientations.generateVonMisesFisher(mu = vect, kappa = 0, N = 10)
self.assertEqual(orientations, None)
#with pytest.raises("spam.orientations.fitVonMisesFisher: The vectors must be an array of Nx3"):
self.assertRaises(AssertionError, spam.orientations.generateVonMisesFisher, mu = vect, kappa = 0, N = 10)
# 2. Check for number of vectors
vect = numpy.array([2,1,1])
orientations = spam.orientations.generateVonMisesFisher(mu = vect, kappa = 1, N = 1)
self.assertEqual(orientations, None)
self.assertRaises(AssertionError, spam.orientations.generateVonMisesFisher,mu = vect, kappa = 1, N = 1)
# 3. Check for main orientation and Kappa
# Generate random main direction
alpha = random.randrange(30, 330, 1)
......@@ -138,20 +141,19 @@ class testAll(unittest.TestCase):
# Check if the difference between the angles is less than 5 degree
self.assertLess(numpy.abs(thetaSVD - theta), 5)
self.assertLess(numpy.abs(alphaSVD - alpha), 5)
def test_fitVonMisesFisher(self):
# 1. Check that the vectors are 3D
orientations = numpy.random.rand(10,5)
res = spam.orientations.fitVonMisesFisher(orientations)
self.assertEqual(res, None)
self.assertRaises(AssertionError, spam.orientations.fitVonMisesFisher, orientations)
# 2. Check for the confidence intervals
orientations = numpy.random.rand(10,3)
res = spam.orientations.fitVonMisesFisher(orientations, confVMF = 2)
self.assertEqual(res, None)
res = spam.orientations.fitVonMisesFisher(orientations, confMu = 2)
self.assertEqual(res, None)
res = spam.orientations.fitVonMisesFisher(orientations, confKappa = 2)
self.assertEqual(res, None)
self.assertRaises(AssertionError, spam.orientations.fitVonMisesFisher, orientations, confVMF = 2)
self.assertRaises(AssertionError, spam.orientations.fitVonMisesFisher, orientations, confMu = 2)
self.assertRaises(AssertionError, spam.orientations.fitVonMisesFisher, orientations, confKappa = 2)
# 3. Check for main orientation and Kappa
# Generate random main direction
alpha = random.randrange(30, 330, 1)
......@@ -166,33 +168,29 @@ class testAll(unittest.TestCase):
N = 10000
# Generate the distribution
orientations = spam.orientations.generateVonMisesFisher(mu = mu, kappa = K, N = N)
# Fit the vectors
# Fit the vectors
res = spam.orientations.fitVonMisesFisher(orientations)
# Check alpha and theta
self.assertLess(numpy.abs(alpha - res['alpha']), 2)
self.assertLess(numpy.abs(theta - res['theta']), 2)
def test_generateIsotropic(self):
# 1. Check for non-int and negative values of number of vectors
res = spam.orientations.generateIsotropic(-1)
self.assertEqual(res, None)
res = spam.orientations.generateIsotropic(4.5)
self.assertEqual(res, None)
res = spam.orientations.generateIsotropic('a')
self.assertEqual(res, None)
self.assertRaises(AssertionError, spam.orientations.generateIsotropic, -1)
self.assertRaises(AssertionError, spam.orientations.generateIsotropic, 4.5)
self.assertRaises(AssertionError, spam.orientations.generateIsotropic, 'a')
# 2. Check that it runs and the output makes sense
vectors = spam.orientations.generateIsotropic(10000)
_,_,a = spam.orientations.fabricTensor(vectors)
self.assertLess(a, 0.05)
def test_generateIcosphere(self):
# 1. Check for non-int and negative values of number of subDiv
res = spam.orientations.generateIcosphere(-1)
self.assertEqual(res, None)
res = spam.orientations.generateIcosphere(4.5)
self.assertEqual(res, None)
res = spam.orientations.generateIcosphere('a')
self.assertEqual(res, None)
self.assertRaises(AssertionError, spam.orientations.generateIcosphere, -1)
self.assertRaises(AssertionError, spam.orientations.generateIcosphere, 4.5)
self.assertRaises(AssertionError, spam.orientations.generateIcosphere, 'a')
# 2. Check that it runs and the output makes sense
vert, face, vect = spam.orientations.generateIcosphere(3)
_,_,a = spam.orientations.fabricTensor(vert)
......@@ -200,8 +198,8 @@ class testAll(unittest.TestCase):
_,_,a = spam.orientations.fabricTensor(vect)
self.assertLess(a, 0.01)
if __name__ == '__main__':
unittest.main()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment