makeinputs #11
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.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
|
from dataclasses import dataclass
|
||||||
import numpy
|
import numpy
|
||||||
import numpy.typing
|
import numpy.typing
|
||||||
from typing import Sequence, List, Tuple
|
from typing import Sequence, List
|
||||||
from pdme.measurement.dot_measure import DotMeasurement, DotRangeMeasurement
|
from pdme.measurement.dot_measure import DotMeasurement, DotRangeMeasurement
|
||||||
|
from pdme.measurement.dot_pair_measure import DotPairMeasurement, DotPairRangeMeasurement
|
||||||
|
from pdme.measurement.input_types import DotInput, DotPairInput
|
||||||
DotInput = Tuple[numpy.typing.ArrayLike, float]
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@ -53,15 +52,8 @@ class OscillatingDipole():
|
|||||||
def _b(self, f: float) -> float:
|
def _b(self, f: float) -> float:
|
||||||
return (1 / numpy.pi) * (self.w / (f**2 + self.w**2))
|
return (1 / numpy.pi) * (self.w / (f**2 + self.w**2))
|
||||||
|
|
||||||
|
def s_for_dot_pair(self, r1: numpy.ndarray, r2: numpy.ndarray, f: float) -> float:
|
||||||
def dot_inputs_to_array(dot_inputs: Sequence[DotInput]) -> numpy.ndarray:
|
return self._alpha(r1) * self._alpha(r2) * self._b(f)
|
||||||
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))
|
|
||||||
|
|
||||||
|
|
||||||
class OscillatingDipoleArrangement():
|
class OscillatingDipoleArrangement():
|
||||||
@ -80,12 +72,24 @@ class OscillatingDipoleArrangement():
|
|||||||
f = dot_input[1]
|
f = dot_input[1]
|
||||||
return DotMeasurement(sum([dipole.s_at_position(r, f) for dipole in self.dipoles]), r, f)
|
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]:
|
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.
|
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]
|
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:
|
def get_percent_range_dot_measurement(self, dot_input: DotInput, low_percent: float, high_percent: float) -> DotRangeMeasurement:
|
||||||
r = numpy.array(dot_input[0])
|
r = numpy.array(dot_input[0])
|
||||||
f = dot_input[1]
|
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]:
|
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]
|
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.")
|
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():
|
def test_range_dipole_measurements():
|
||||||
d1 = pdme.measurement.OscillatingDipole((1, 2, 3), (4, 5, 6), 7)
|
d1 = pdme.measurement.OscillatingDipole((1, 2, 3), (4, 5, 6), 7)
|
||||||
d2 = pdme.measurement.OscillatingDipole((2, 5, 3), (4, -5, -6), 2)
|
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