Adds better test for static dipole as well as calculating dot measurements
All checks were successful
gitea-physics/pathfinder/pipeline/head This commit looks good
All checks were successful
gitea-physics/pathfinder/pipeline/head This commit looks good
This commit is contained in:
parent
0e3eddebcc
commit
4011a5c698
@ -1,5 +1,5 @@
|
|||||||
from pathfinder.model.dot import DotMeasurement
|
from pathfinder.model.dot import DotMeasurement
|
||||||
from pathfinder.model.model import DotDipoleModel
|
from pathfinder.model.model import DotDipoleModel
|
||||||
from pathfinder.model.staticdipole import StaticDipole
|
from pathfinder.model.staticdipole import StaticDipoleArrangement, StaticDipole
|
||||||
|
|
||||||
__all__ = ['DotMeasurement', 'DotDipoleModel', 'StaticDipole']
|
__all__ = ['DotMeasurement', 'DotDipoleModel', 'StaticDipoleArrangement', 'StaticDipole']
|
||||||
|
@ -2,8 +2,6 @@ from dataclasses import dataclass
|
|||||||
import numpy
|
import numpy
|
||||||
import numpy.typing
|
import numpy.typing
|
||||||
|
|
||||||
from pathfinder.model.staticdipole import StaticDipole
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class DotMeasurement():
|
class DotMeasurement():
|
||||||
@ -38,9 +36,8 @@ class DotMeasurement():
|
|||||||
p = pt[0:3] # hardcoded here because chances
|
p = pt[0:3] # hardcoded here because chances
|
||||||
s = pt[3:6] # are we'll only ever work in 3d.
|
s = pt[3:6] # are we'll only ever work in 3d.
|
||||||
|
|
||||||
dipole = StaticDipole(p, s)
|
diff = self.r - s
|
||||||
|
return p.dot(diff) / (numpy.linalg.norm(diff)**3)
|
||||||
return dipole.v_at_position(self.r)
|
|
||||||
|
|
||||||
def cost(self, pts: numpy.ndarray) -> float:
|
def cost(self, pts: numpy.ndarray) -> float:
|
||||||
# 6 because dipole in 3d has 6 degrees of freedom.
|
# 6 because dipole in 3d has 6 degrees of freedom.
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
import numpy
|
import numpy
|
||||||
import numpy.typing
|
import numpy.typing
|
||||||
|
from typing import Sequence, List
|
||||||
|
from pathfinder.model.dot import DotMeasurement
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@ -20,12 +22,37 @@ class StaticDipole():
|
|||||||
|
|
||||||
def __post_init__(self) -> None:
|
def __post_init__(self) -> None:
|
||||||
'''
|
'''
|
||||||
Coerce the inputs into numpy arrays.
|
Coerce the inputs into numpy arrays.
|
||||||
'''
|
'''
|
||||||
self.p = numpy.array(self.p)
|
self.p = numpy.array(self.p)
|
||||||
self.s = numpy.array(self.s)
|
self.s = numpy.array(self.s)
|
||||||
|
|
||||||
def v_at_position(self, r: numpy.typing.ArrayLike) -> float:
|
def v_at_position(self, r: numpy.ndarray) -> float:
|
||||||
|
'''
|
||||||
|
Mirrors the same function in pathfinder.model.dot.
|
||||||
|
'''
|
||||||
diff = r - self.s
|
diff = r - self.s
|
||||||
return self.p.dot(diff) / (numpy.linalg.norm(diff)**3)
|
return self.p.dot(diff) / (numpy.linalg.norm(diff)**3)
|
||||||
|
|
||||||
|
|
||||||
|
class StaticDipoleArrangement():
|
||||||
|
'''
|
||||||
|
A collection of static dipoles, which we are interested in being able to characterise.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
--------
|
||||||
|
dipoles : Sequence[StaticDipole]
|
||||||
|
'''
|
||||||
|
def __init__(self, dipoles):
|
||||||
|
self.dipoles = dipoles
|
||||||
|
|
||||||
|
def get_dot_measurement(self, dot_position: numpy.typing.ArrayLike) -> DotMeasurement:
|
||||||
|
r = numpy.array(dot_position)
|
||||||
|
return DotMeasurement(sum([dipole.v_at_position(r) for dipole in self.dipoles]), r)
|
||||||
|
|
||||||
|
def get_dot_measurements(self, dot_positions: Sequence[numpy.typing.ArrayLike]) -> List[DotMeasurement]:
|
||||||
|
'''
|
||||||
|
For a series of points, each with three coordinates, return
|
||||||
|
'''
|
||||||
|
|
||||||
|
return [self.get_dot_measurement(dot_position) for dot_position in dot_positions]
|
||||||
|
23
tests/model/test_staticdipole.py
Normal file
23
tests/model/test_staticdipole.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import numpy
|
||||||
|
import pathfinder.model as model
|
||||||
|
|
||||||
|
|
||||||
|
def test_static_dipole():
|
||||||
|
d1 = model.StaticDipole((1, 2, 3), (4, 5, 6))
|
||||||
|
d2 = model.StaticDipole((4, 5, 6), (1, 2, 3))
|
||||||
|
dipoles = model.StaticDipoleArrangement([d1, d2])
|
||||||
|
|
||||||
|
dot_position1 = (-1, -1, -1)
|
||||||
|
expected_v1 = -0.3338923121348659
|
||||||
|
|
||||||
|
numpy.testing.assert_allclose(dipoles.get_dot_measurement(dot_position1).v, expected_v1, err_msg="Voltage at dot isn't as expected.")
|
||||||
|
numpy.testing.assert_allclose(dipoles.get_dot_measurement(dot_position1).r, dot_position1, err_msg="Dot isn't where expected.")
|
||||||
|
|
||||||
|
# test multiple dots
|
||||||
|
dot_position2 = (-1, -1, -5)
|
||||||
|
expected_v2 = -0.1254445237566694
|
||||||
|
|
||||||
|
both_measurements = dipoles.get_dot_measurements([dot_position1, dot_position2])
|
||||||
|
measured_voltages = numpy.sort([m.v for m in both_measurements])
|
||||||
|
expected_measured_voltages = numpy.sort([expected_v1, expected_v2])
|
||||||
|
numpy.testing.assert_allclose(measured_voltages, expected_measured_voltages, err_msg="Didn't get the measured voltages expected")
|
Reference in New Issue
Block a user