|
31 | 31 | nprect = np.vectorize(rect)
|
32 | 32 |
|
33 | 33 |
|
| 34 | +def from_db(x: float, factor: int = 10) -> float: |
| 35 | + """Converts a dB value to a linear value.""" |
| 36 | + return 10 ** (x / factor) |
| 37 | + |
| 38 | + |
| 39 | +def to_db(x: float, factor: int = 10) -> float: |
| 40 | + """Converts a linear value to a dB value.""" |
| 41 | + return factor * np.log10(x) |
| 42 | + |
| 43 | + |
34 | 44 | class Simulation:
|
35 | 45 | """This class instantiates a simulation context.
|
36 | 46 |
|
@@ -406,7 +416,7 @@ def __init__(
|
406 | 416 | self._coupled_powers = np.array([])
|
407 | 417 | self._freqs = np.array([freq if freq else wl2freq(wl)])
|
408 | 418 | self._powers = np.array([power])
|
409 |
| - self.coupling_ratio = 10 ** (-np.abs(coupling_loss) / 10) |
| 419 | + self.coupling_ratio = from_db(-np.abs(coupling_loss)) |
410 | 420 | self.freqs = np.array([])
|
411 | 421 | self.index = 0
|
412 | 422 | self.phase = phase
|
@@ -437,11 +447,7 @@ def get_rin(self, bandwidth: float) -> float:
|
437 | 447 | bandwidth :
|
438 | 448 | The bandwidth of the detector in Hz.
|
439 | 449 | """
|
440 |
| - return ( |
441 |
| - 0 |
442 |
| - if self.rin == -np.inf |
443 |
| - else 10 * np.log10((10 ** (self.rin / 10)) * bandwidth) |
444 |
| - ) |
| 450 | + return 0 if self.rin == -np.inf else to_db(from_db(self.rin) * bandwidth) |
445 | 451 |
|
446 | 452 | def get_rin_dist(self, i: int, j: int) -> List[float]:
|
447 | 453 | """Returns the normal distribution used for the i,j key. If this is the
|
@@ -557,7 +563,7 @@ def _detect(self, power: List[np.ndarray]) -> List[np.ndarray]:
|
557 | 563 |
|
558 | 564 | # calculate the standard deviation of the RIN noise
|
559 | 565 | std = (
|
560 |
| - 10 ** ((10 * np.log10(power[i][j][0]) + rin) / 20) |
| 566 | + from_db(to_db(power[i][j][0]) + rin, 20) |
561 | 567 | if power[i][j][0]
|
562 | 568 | else 0
|
563 | 569 | )
|
@@ -715,21 +721,28 @@ def _detect(self, powers: List[np.ndarray]) -> List[np.ndarray]:
|
715 | 721 | rf_rin = source.get_rin(self._get_rf_bandwidth()[0])
|
716 | 722 | dist = source.get_rin_dist(i, j)
|
717 | 723 |
|
| 724 | + # if the two powers are different, we need to adjust |
| 725 | + # the CMRR to account for the difference |
| 726 | + cmrr = self.rf_cmrr |
| 727 | + sum = p1[i][j][0] + p2[i][j][0] |
| 728 | + diff = np.abs(p1[i][j][0] - p2[i][j][0]) |
| 729 | + if diff: |
| 730 | + cmrr2 = -to_db(sum / diff) |
| 731 | + cmrr = to_db( |
| 732 | + np.sqrt(from_db(cmrr) ** 2 + from_db(cmrr2) ** 2) |
| 733 | + ) |
| 734 | + |
718 | 735 | # only calculate the noise if there is power
|
719 | 736 | if p1[i][j][0] > 0:
|
720 |
| - p1db = 10 * np.log10(p1[i][j][0]) |
721 |
| - monitor_noise1 += (10 ** ((p1db + monitor_rin) / 20)) * dist |
722 |
| - rf_noise1 += ( |
723 |
| - 10 ** ((p1db + rf_rin + self.rf_cmrr) / 20) |
724 |
| - ) * dist |
| 737 | + p1db = to_db(p1[i][j][0]) |
| 738 | + monitor_noise1 += from_db(p1db + monitor_rin, 20) * dist |
| 739 | + rf_noise1 += from_db(p1db + rf_rin + cmrr, 20) * dist |
725 | 740 |
|
726 | 741 | # only calculate the noise if there is power
|
727 | 742 | if p2[i][j][0] > 0:
|
728 |
| - p2db = 10 * np.log10(p2[i][j][0]) |
729 |
| - monitor_noise2 += (10 ** ((p2db + monitor_rin) / 20)) * dist |
730 |
| - rf_noise2 += ( |
731 |
| - 10 ** ((p2db + rf_rin + self.rf_cmrr) / 20) |
732 |
| - ) * dist |
| 743 | + p2db = to_db(p2[i][j][0]) |
| 744 | + monitor_noise2 += from_db(p2db + monitor_rin, 20) * dist |
| 745 | + rf_noise2 += from_db(p2db + rf_rin + cmrr, 20) * dist |
733 | 746 |
|
734 | 747 | # store the RIN noise for later use
|
735 | 748 | self.monitor_rin_dists1[i][j] = monitor_noise1
|
|
0 commit comments