Merge pull request 'makeinputs' (#11) from makeinputs into master
All checks were successful
gitea-physics/pdme/pipeline/head This commit looks good
All checks were successful
gitea-physics/pdme/pipeline/head This commit looks good
Reviewed-on: #11
This commit is contained in:
commit
5321fb2071
4
pdme/inputs/__init__.py
Normal file
4
pdme/inputs/__init__.py
Normal file
@ -0,0 +1,4 @@
|
||||
from pdme.inputs.dot_inputs import inputs_with_frequency_range, input_pairs_with_frequency_range
|
||||
|
||||
|
||||
__all__ = ['inputs_with_frequency_range', 'input_pairs_with_frequency_range']
|
13
pdme/inputs/dot_inputs.py
Normal file
13
pdme/inputs/dot_inputs.py
Normal file
@ -0,0 +1,13 @@
|
||||
import numpy
|
||||
import numpy.typing
|
||||
import itertools
|
||||
from typing import Sequence, Tuple
|
||||
|
||||
|
||||
def inputs_with_frequency_range(dots: Sequence[numpy.typing.ArrayLike], frequency_range: Sequence[float]) -> Sequence[Tuple[numpy.typing.ArrayLike, float]]:
|
||||
return list(itertools.chain(*[[(dot, f) for f in frequency_range] for dot in dots]))
|
||||
|
||||
|
||||
def input_pairs_with_frequency_range(dots: Sequence[numpy.typing.ArrayLike], frequency_range: Sequence[float]) -> Sequence[Tuple[numpy.typing.ArrayLike, numpy.typing.ArrayLike, float]]:
|
||||
all_pairs = itertools.combinations(dots, 2)
|
||||
return list(itertools.chain(*[[(dot1, dot2, f) for f in frequency_range] for (dot1, dot2) in all_pairs]))
|
@ -1,4 +1,7 @@
|
||||
from pdme.measurement.dot_measure import DotMeasurement
|
||||
from pdme.measurement.dot_measure import DotMeasurement, DotRangeMeasurement
|
||||
from pdme.measurement.dot_pair_measure import DotPairMeasurement, DotPairRangeMeasurement
|
||||
from pdme.measurement.oscillating_dipole import OscillatingDipole, OscillatingDipoleArrangement
|
||||
from pdme.measurement.input_types import DotInput, DotPairInput
|
||||
|
||||
__all__ = ['DotMeasurement', 'DotRangeMeasurement', 'OscillatingDipole', 'OscillatingDipoleArrangement']
|
||||
|
||||
__all__ = ['DotMeasurement', 'DotRangeMeasurement', 'DotPairMeasurement', 'DotPairRangeMeasurement', 'OscillatingDipole', 'OscillatingDipoleArrangement', 'DotInput', 'DotPairInput']
|
||||
|
58
pdme/measurement/dot_pair_measure.py
Normal file
58
pdme/measurement/dot_pair_measure.py
Normal file
@ -0,0 +1,58 @@
|
||||
from dataclasses import dataclass
|
||||
import numpy
|
||||
import numpy.typing
|
||||
|
||||
|
||||
@dataclass
|
||||
class DotPairMeasurement():
|
||||
'''
|
||||
Representation of a dot measuring oscillating dipoles.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
v : float
|
||||
The voltage measured at the dot.
|
||||
r1 : numpy.ndarray
|
||||
The position of the first dot.
|
||||
r2 : numpy.ndarray
|
||||
The position of the second dot.
|
||||
f : float
|
||||
The measurement frequency.
|
||||
'''
|
||||
v: float
|
||||
r1: numpy.ndarray
|
||||
r2: numpy.ndarray
|
||||
f: float
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
self.r1 = numpy.array(self.r1)
|
||||
self.r2 = numpy.array(self.r2)
|
||||
|
||||
|
||||
@dataclass
|
||||
class DotPairRangeMeasurement():
|
||||
'''
|
||||
Representation of a dot measuring oscillating dipoles.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
v_low : float
|
||||
The lower range of voltage measured at the dot.
|
||||
v_high : float
|
||||
The upper range of voltage measured at the dot.
|
||||
r1 : numpy.ndarray
|
||||
The position of the first dot.
|
||||
r2 : numpy.ndarray
|
||||
The position of the second dot.
|
||||
f : float
|
||||
The measurement frequency.
|
||||
'''
|
||||
v_low: float
|
||||
v_high: float
|
||||
r1: numpy.ndarray
|
||||
r2: numpy.ndarray
|
||||
f: float
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
self.r1 = numpy.array(self.r1)
|
||||
self.r2 = numpy.array(self.r2)
|
22
pdme/measurement/input_types.py
Normal file
22
pdme/measurement/input_types.py
Normal file
@ -0,0 +1,22 @@
|
||||
import numpy.typing
|
||||
from typing import Tuple, Sequence, Union
|
||||
from pdme.measurement.dot_measure import DotRangeMeasurement
|
||||
from pdme.measurement.dot_pair_measure import DotPairRangeMeasurement
|
||||
|
||||
|
||||
DotInput = Tuple[numpy.typing.ArrayLike, float]
|
||||
DotPairInput = Tuple[numpy.typing.ArrayLike, numpy.typing.ArrayLike, float]
|
||||
|
||||
|
||||
def dot_inputs_to_array(dot_inputs: Sequence[DotInput]) -> numpy.ndarray:
|
||||
return numpy.array([numpy.append(numpy.array(input[0]), input[1]) for input in dot_inputs])
|
||||
|
||||
|
||||
def dot_pair_inputs_to_array(pair_inputs: Sequence[DotPairInput]) -> numpy.ndarray:
|
||||
return numpy.array([[numpy.append(numpy.array(input[0]), input[2]), numpy.append(numpy.array(input[1]), input[2])] for input in pair_inputs])
|
||||
|
||||
|
||||
def dot_range_measurements_low_high_arrays(dot_range_measurements: Union[Sequence[DotRangeMeasurement], Sequence[DotPairRangeMeasurement]]) -> Tuple[numpy.ndarray, numpy.ndarray]:
|
||||
lows = [measurement.v_low for measurement in dot_range_measurements]
|
||||
highs = [measurement.v_high for measurement in dot_range_measurements]
|
||||
return (numpy.array(lows), numpy.array(highs))
|
@ -1,11 +1,10 @@
|
||||
from dataclasses import dataclass
|
||||
import numpy
|
||||
import numpy.typing
|
||||
from typing import Sequence, List, Tuple
|
||||
from typing import Sequence, List
|
||||
from pdme.measurement.dot_measure import DotMeasurement, DotRangeMeasurement
|
||||
|
||||
|
||||
DotInput = Tuple[numpy.typing.ArrayLike, float]
|
||||
from pdme.measurement.dot_pair_measure import DotPairMeasurement, DotPairRangeMeasurement
|
||||
from pdme.measurement.input_types import DotInput, DotPairInput
|
||||
|
||||
|
||||
@dataclass
|
||||
@ -53,15 +52,8 @@ class OscillatingDipole():
|
||||
def _b(self, f: float) -> float:
|
||||
return (1 / numpy.pi) * (self.w / (f**2 + self.w**2))
|
||||
|
||||
|
||||
def dot_inputs_to_array(dot_inputs: Sequence[DotInput]) -> numpy.ndarray:
|
||||
return numpy.array([numpy.append(numpy.array(input[0]), input[1]) for input in dot_inputs])
|
||||
|
||||
|
||||
def dot_range_measurements_low_high_arrays(dot_range_measurements: Sequence[DotRangeMeasurement]) -> Tuple[numpy.ndarray, numpy.ndarray]:
|
||||
lows = [measurement.v_low for measurement in dot_range_measurements]
|
||||
highs = [measurement.v_high for measurement in dot_range_measurements]
|
||||
return (numpy.array(lows), numpy.array(highs))
|
||||
def s_for_dot_pair(self, r1: numpy.ndarray, r2: numpy.ndarray, f: float) -> float:
|
||||
return self._alpha(r1) * self._alpha(r2) * self._b(f)
|
||||
|
||||
|
||||
class OscillatingDipoleArrangement():
|
||||
@ -80,12 +72,24 @@ class OscillatingDipoleArrangement():
|
||||
f = dot_input[1]
|
||||
return DotMeasurement(sum([dipole.s_at_position(r, f) for dipole in self.dipoles]), r, f)
|
||||
|
||||
def get_dot_pair_measurement(self, dot_pair_input: DotPairInput) -> DotPairMeasurement:
|
||||
r1 = numpy.array(dot_pair_input[0])
|
||||
r2 = numpy.array(dot_pair_input[1])
|
||||
f = dot_pair_input[2]
|
||||
return DotPairMeasurement(sum([dipole.s_for_dot_pair(r1, r2, f) for dipole in self.dipoles]), r1, r2, f)
|
||||
|
||||
def get_dot_measurements(self, dot_inputs: Sequence[DotInput]) -> List[DotMeasurement]:
|
||||
'''
|
||||
For a series of points, each with three coordinates and a frequency, return a list of the corresponding DotMeasurements.
|
||||
'''
|
||||
return [self.get_dot_measurement(dot_input) for dot_input in dot_inputs]
|
||||
|
||||
def get_dot_pair_measurements(self, dot_pair_inputs: Sequence[DotPairInput]) -> List[DotPairMeasurement]:
|
||||
'''
|
||||
For a series of pairs of points, each with three coordinates and a frequency, return a list of the corresponding DotPairMeasurements.
|
||||
'''
|
||||
return [self.get_dot_pair_measurement(dot_pair_input) for dot_pair_input in dot_pair_inputs]
|
||||
|
||||
def get_percent_range_dot_measurement(self, dot_input: DotInput, low_percent: float, high_percent: float) -> DotRangeMeasurement:
|
||||
r = numpy.array(dot_input[0])
|
||||
f = dot_input[1]
|
||||
@ -93,6 +97,18 @@ class OscillatingDipoleArrangement():
|
||||
|
||||
def get_percent_range_dot_measurements(self, dot_inputs: Sequence[DotInput], low_percent: float, high_percent: float) -> List[DotRangeMeasurement]:
|
||||
'''
|
||||
For a series of points, each with three coordinates and a frequency, and also a lower error range and upper error range, return a list of the corresponding DotRangeMeasurements.
|
||||
For a series of pairs of points, each with three coordinates and a frequency, and also a lower error range and upper error range, return a list of the corresponding DotPairRangeMeasurements.
|
||||
'''
|
||||
return [self.get_percent_range_dot_measurement(dot_input, low_percent, high_percent) for dot_input in dot_inputs]
|
||||
|
||||
def get_percent_range_dot_pair_measurement(self, pair_input: DotPairInput, low_percent: float, high_percent: float) -> DotPairRangeMeasurement:
|
||||
r1 = numpy.array(pair_input[0])
|
||||
r2 = numpy.array(pair_input[1])
|
||||
f = pair_input[2]
|
||||
return DotPairRangeMeasurement(low_percent * sum([dipole.s_for_dot_pair(r1, r2, f) for dipole in self.dipoles]), high_percent * sum([dipole.s_for_dot_pair(r1, r2, f) for dipole in self.dipoles]), r1, r2, f)
|
||||
|
||||
def get_percent_range_dot_pair_measurements(self, pair_inputs: Sequence[DotPairInput], low_percent: float, high_percent: float) -> List[DotPairRangeMeasurement]:
|
||||
'''
|
||||
For a series of pairs of points, each with three coordinates and a frequency, and also a lower error range and upper error range, return a list of the corresponding DotPairRangeMeasurements.
|
||||
'''
|
||||
return [self.get_percent_range_dot_pair_measurement(pair_input, low_percent, high_percent) for pair_input in pair_inputs]
|
||||
|
31
tests/inputs/test_dot_inputs.py
Normal file
31
tests/inputs/test_dot_inputs.py
Normal file
@ -0,0 +1,31 @@
|
||||
import pdme.inputs
|
||||
|
||||
|
||||
def test_inputs_with_frequency_range():
|
||||
dot1 = [1, 2, 3]
|
||||
dot2 = [2, 4, 6]
|
||||
|
||||
frequencies = [5, 7, 9]
|
||||
|
||||
expected = [
|
||||
([1, 2, 3], 5), ([1, 2, 3], 7), ([1, 2, 3], 9), ([2, 4, 6], 7), ([2, 4, 6], 9), ([2, 4, 6], 5)
|
||||
]
|
||||
|
||||
actual = pdme.inputs.inputs_with_frequency_range([dot1, dot2], frequencies)
|
||||
|
||||
assert sorted(actual) == sorted(expected), "Did not actually match dot inputs!"
|
||||
|
||||
|
||||
def test_input_pairs_with_frequency_range():
|
||||
dot1 = [1, 2, 3]
|
||||
dot2 = [2, 4, 6]
|
||||
|
||||
frequencies = [5, 7, 9]
|
||||
|
||||
expected = [
|
||||
([1, 2, 3], [2, 4, 6], 5), ([1, 2, 3], [2, 4, 6], 7), ([1, 2, 3], [2, 4, 6], 9)
|
||||
]
|
||||
|
||||
actual = pdme.inputs.input_pairs_with_frequency_range([dot1, dot2], frequencies)
|
||||
|
||||
assert sorted(actual) == sorted(expected), "Did not actually match dot inputs!"
|
@ -22,6 +22,34 @@ def test_static_dipole():
|
||||
numpy.testing.assert_allclose(measurement.v, expected_v1 + expected_v2, err_msg="Voltage at dot isn't as expected.")
|
||||
|
||||
|
||||
def test_dipole_dot_pair():
|
||||
d1 = pdme.measurement.OscillatingDipole((1, 2, 3), (4, 5, 6), 7)
|
||||
dipoles = pdme.measurement.OscillatingDipoleArrangement([d1])
|
||||
|
||||
dot_position1 = (-1, -1, -1)
|
||||
dot_position2 = (1, 2, 3)
|
||||
dot_frequency = 8
|
||||
expected_sij = 0.000083328037100902801698
|
||||
|
||||
numpy.testing.assert_allclose(d1.s_for_dot_pair(dot_position1, dot_position2, dot_frequency), expected_sij, err_msg="Sij for dot pair isn't as expected.")
|
||||
numpy.testing.assert_allclose([m.v for m in dipoles.get_dot_pair_measurements([(dot_position1, dot_position2, dot_frequency)])], [expected_sij], err_msg="Sij for dot pair isn't as expected via dipole.")
|
||||
|
||||
|
||||
def test_range_pairs():
|
||||
d1 = pdme.measurement.OscillatingDipole((1, 2, 3), (4, 5, 6), 7)
|
||||
dipoles = pdme.measurement.OscillatingDipoleArrangement([d1])
|
||||
|
||||
dot_position1 = (-1, -1, -1)
|
||||
dot_position2 = (1, 2, 3)
|
||||
dot_frequency = 8
|
||||
expected_sij = 0.000083328037100902801698
|
||||
|
||||
actuals = dipoles.get_percent_range_dot_pair_measurements([(dot_position1, dot_position2, dot_frequency)], 0.5, 1.5)
|
||||
assert len(actuals) == 1, "should have only been one pair"
|
||||
actual = actuals[0]
|
||||
numpy.testing.assert_allclose([actual.v_low, actual.v_high], expected_sij * numpy.array([0.5, 1.5]), err_msg="Sij for dot pair isn't as expected via dipole with range.")
|
||||
|
||||
|
||||
def test_range_dipole_measurements():
|
||||
d1 = pdme.measurement.OscillatingDipole((1, 2, 3), (4, 5, 6), 7)
|
||||
d2 = pdme.measurement.OscillatingDipole((2, 5, 3), (4, -5, -6), 2)
|
||||
|
45
tests/measurement/test_measurement_to_arrays.py
Normal file
45
tests/measurement/test_measurement_to_arrays.py
Normal file
@ -0,0 +1,45 @@
|
||||
import numpy
|
||||
import pdme.measurement.input_types
|
||||
from pdme.measurement.dot_measure import DotRangeMeasurement
|
||||
from pdme.measurement.dot_pair_measure import DotPairRangeMeasurement
|
||||
|
||||
|
||||
def test_inputs_to_array():
|
||||
i1 = ([1, 2, 3], 5)
|
||||
i2 = ([-1, 4, -2], 9)
|
||||
|
||||
actual = pdme.measurement.input_types.dot_inputs_to_array([i1, i2])
|
||||
expected = numpy.array([[1, 2, 3, 5], [-1, 4, -2, 9]])
|
||||
|
||||
numpy.testing.assert_allclose(actual, expected, err_msg="Didn't convert to array properly")
|
||||
|
||||
|
||||
def test_pair_inputs_to_array():
|
||||
i1 = ([1, 2, 3], [-1, 4, -2], 5)
|
||||
i2 = ([-1, 4, -2], [6, 7, 8], 9)
|
||||
|
||||
actual = pdme.measurement.input_types.dot_pair_inputs_to_array([i1, i2])
|
||||
expected = numpy.array([
|
||||
[[1, 2, 3, 5], [-1, 4, -2, 5]],
|
||||
[[-1, 4, -2, 9], [6, 7, 8, 9]],
|
||||
])
|
||||
|
||||
numpy.testing.assert_allclose(actual, expected, err_msg="Didn't convert to array properly")
|
||||
|
||||
|
||||
def test_ranges_to_array():
|
||||
m1 = DotRangeMeasurement(1, 2, 100, 1000)
|
||||
m2 = DotRangeMeasurement(0.5, 3, 100, 1000)
|
||||
|
||||
actual_lows, actual_highs = pdme.measurement.input_types.dot_range_measurements_low_high_arrays([m1, m2])
|
||||
numpy.testing.assert_allclose(actual_lows, [1, 0.5], err_msg="Lows were wrong")
|
||||
numpy.testing.assert_allclose(actual_highs, [2, 3], err_msg="Highs were wrong")
|
||||
|
||||
|
||||
def test_pair_ranges_to_array():
|
||||
m1 = DotPairRangeMeasurement(1, 2, 100, 1000, 10000)
|
||||
m2 = DotPairRangeMeasurement(0.5, 3, 100, 1000, 10000)
|
||||
|
||||
actual_lows, actual_highs = pdme.measurement.input_types.dot_range_measurements_low_high_arrays([m1, m2])
|
||||
numpy.testing.assert_allclose(actual_lows, [1, 0.5], err_msg="Lows were wrong")
|
||||
numpy.testing.assert_allclose(actual_highs, [2, 3], err_msg="Highs were wrong")
|
Loading…
x
Reference in New Issue
Block a user