diff --git a/pymeeus/JupiterMoons.py b/pymeeus/JupiterMoons.py index f338eed..b411336 100644 --- a/pymeeus/JupiterMoons.py +++ b/pymeeus/JupiterMoons.py @@ -952,19 +952,23 @@ def check_phenomena(epoch, check_all=True, i_sat=0): @staticmethod def is_phenomena(epoch): """This method checks if the given coordinates correspond with any - satellite - phenomena. It returns the type of phenomena for all satellites. - + satellite phenomena. It also determines conjunction status such as + moon in occultation, moon in transit, moon in eclipse, shadow Transit + :param epoch: Epoch the calculations should be made for :type epoch: :py:class:'Epoch' - :returns: Result matrix for the four Galilean satellites - Row 0: Io Column 0: Occultation - Row 1: Europa Column 1: Eclipse - Row 2: Ganymede Column 2: No use - Row 3: Callisto - :rtype: tuple - + Row 0: Io Column 0: Earth Occultation + Row 1: Europa Column 1: Sun Occultation + Row 2: Ganymede Column 2: Occultation Type [Earth-Superior Conjunction, Sun-Superior Conjunction] + Row 3: Callisto + + Occultation Type (Superior Conjunction) + Column 1: Earth-Superior Conjunction (True: Jupiter occults moon, False: moon transits jupiter) + Column 2: Sun-Superior Conjunction (True: moon enters eclipse, False: shadow transits jupiter) + + :rtype: list + :raises: TypeError if input values are wrong type Calculation of result matrix for December 16 at 0h UTC @@ -972,24 +976,24 @@ def is_phenomena(epoch): >>> utc_1992_12_16_00_00_00 = Epoch(1992, 12, 16, utc=True) >>> result_matrix = JupiterMoons.is_phenomena(utc_1992_12_16_00_00_00) >>> print(result_matrix[0]) - [False, False, False] + [False, False, [None, None]] >>> print(result_matrix[1]) - [False, False, False] + [False, False, [None, None]] >>> print(result_matrix[2]) - [False, False, False] + [False, False, [None, None]] >>> print(result_matrix[3]) - [False, False, False] + [False, False, [None, None]] >>> io_ecc_start_2021_02_12_14_19_14 = Epoch(2021, 2, 12.5966898148148) >>> result_matrix = JupiterMoons.is_phenomena( \ - io_ecc_start_2021_02_12_14_19_14) + >>> io_ecc_start_2021_02_12_14_19_14) >>> print(result_matrix[0]) - [False, True, False] + [False, True, [None, True]] >>> print(result_matrix[1]) - [False, False, False] + [False, False, [None, None]] >>> print(result_matrix[2]) - [False, False, False] + [False, False, [None, None]] >>> print(result_matrix[3]) - [False, False, False] + [False, False, [None, None]] """ # Get distance Matrix @@ -1002,7 +1006,15 @@ def is_phenomena(epoch): for row in range(len(result_matrix)): for col in range(len(result_matrix[row]) - 1): - result_matrix[row][col] = (1 >= dist_matrix[row][col] >= 1) + # Occultation and Eclipse check within -1 and 1 + result_matrix[row][col] = (1 >= dist_matrix[row][col] >= -1) + + # Determine Occultation status for the third column + # Check Earth-based and Sun-based distances only if there's a Occultation + earth_based = dist_matrix[row][0] >= 0 if result_matrix[row][0] else None + sun_based = dist_matrix[row][1] >= 0 if result_matrix[row][1] else None + + result_matrix[row][2] = [earth_based, sun_based] return result_matrix @@ -1272,6 +1284,8 @@ def print_me(msg, val): # Row 1: Europa Column 1: perspective distance as seen from the Sun # Row 2: Ganymede Column 2: No use # Row 3: Callisto + +# ToDo update test # print Row 0 print( @@ -1309,31 +1323,35 @@ def print_me(msg, val): io_ecc_start_2021_02_12_14_19_14 = Epoch(2021, 2, 12.5966898148148) # Structure of result matrix - # Row 0: Io Column 0: Occultation True\False - # Row 1: Europa Column 1: Eclipse True\False - # Row 2: Ganymede Column 2: No use - # Row 3: Callisto + # Row 0: Io Column 0: Earth Occultation + # Row 1: Europa Column 1: Sun Occultation + # Row 2: Ganymede Column 2: Occultation Type [Earth-Superior Conjunction, Sun-Superior Conjunction] + # Row 3: Callisto + + # Occultation Type (Superior Conjunction) + # Column 1: Earth-Superior Conjunction (True: Jupiter occults moon, False: moon transits jupiter) + # Column 2: Sun-Superior Conjunction (True: moon enters eclipse, False: shadow transits jupiter) result_matrix = JupiterMoons.is_phenomena(io_ecc_start_2021_02_12_14_19_14) - # print Row 0 - print("(Occultation of Io, Eclipse of Io, No use): ") + # Print Row 0 + print("(Earth Occultation of Io, Sun Occultation of Io, [Superior Conjunction (Earth), Superior Conjunction (Sun)]):") print(result_matrix[0]) - # [False, True, False] + # Expected Output: [False, True, [None, True]] - # print Row 1 - print(" (Occultation of Europa, Eclipse of Europa, No use): ") + # Print Row 1 + print("(Earth Occultation of Europa, Sun Occultation of Europa, [Superior Conjunction (Earth), Superior Conjunction (Sun)]):") print(result_matrix[1]) - # [False, False, False] + # Expected Output: [False, False, [None, None]] - # print Row 2 - print(" (Occultation of Ganymede, Eclipse of Gaymede, No use): ") + # Print Row 2 + print("(Earth Occultation of Ganymede, Sun Occultation of Ganymede, [Superior Conjunction (Earth), Superior Conjunction (Sun)]):") print(result_matrix[2]) - # [False,False,False] + # Expected Output: [False, False, [None, None]] - # print Row 3 - print("(Occultation of Callisto, Eclipse of Callisto, No use): ") + # Print Row 3 + print("(Earth Occultation of Callisto, Sun Occultation of Callisto, [Superior Conjunction (Earth), Superior Conjunction (Sun)]):") print(result_matrix[3]) - # [False,False,False] + # Expected Output: [False, False, [None, None]] print("") diff --git a/tests/test_jupiterMoons.py b/tests/test_jupiterMoons.py index 73f50a8..0d6f7d3 100644 --- a/tests/test_jupiterMoons.py +++ b/tests/test_jupiterMoons.py @@ -257,85 +257,117 @@ def test_check_phenomena(self): col]) < TOL, \ """ERROR: check_phenomena() test doesn't match""" - def test_is_phenomena(self): - """This method tests if the method check_phenomena() returns the - right perspective distances - between the Galilean satellites and Jupiter""" - utc_1992_12_16_00_00_00 = Epoch(EPOCH_1992_12_16_UTC, utc=True) + + def test_is_phenomena(self): + """ + This test checks the `is_phenomena()` method which + returns the result matrix including "conjunction type" + + Each row corresponds to one Galilean satellite (Io, Europa, Ganymede, Callisto). + Each row is: [earth_conjunction, sun_conjunction, [Earth_Superior_Conjunction, Sun_Superior_Conjunction]] + """ + + # + # 1) Check that on 1992-12-16, everything is False/None + # + utc_1992_12_16_00_00_00 = Epoch(1992, 12, 16, utc=True) result_matrix = JupiterMoons.is_phenomena(utc_1992_12_16_00_00_00) - result_matrix_expect = [[False, False, False], - [False, False, False], - [False, False, False], - [False, False, False]] - for row in range(3): + + # Expect everything to be False for columns 0 and 1, and [None, None] in column 2 + result_matrix_expect = [ + [False, False, [None, None]], + [False, False, [None, None]], + [False, False, [None, None]], + [False, False, [None, None]] + ] + + for row in range(4): + # Check columns 0 and 1 for col in range(2): - assert abs( - result_matrix[row][col] - result_matrix_expect[row][ - col]) < TOL, \ - """ERROR: is_phenomena() test one doesn't match""" + assert result_matrix[row][col] == result_matrix_expect[row][col], \ + f"ERROR: Row {row}, col {col} mismatch on 1992-12-16!" + # Check [earth_based, sun_based] + assert result_matrix[row][2] == result_matrix_expect[row][2], \ + f"ERROR: Row {row}, col 2 mismatch on 1992-12-16!" io_ecc_start_2021_02_12_14_19_14 = Epoch(2021, 2, 12.5966898148148) - result_matrix = JupiterMoons.is_phenomena( - io_ecc_start_2021_02_12_14_19_14) - result_matrix_expect[0][1] = True + result_matrix = JupiterMoons.is_phenomena(io_ecc_start_2021_02_12_14_19_14) - for row in range(3): + result_matrix_expect = [ + [False, True, [None, True]], # Io + [False, False, [None, None]], # Europa + [False, False, [None, None]], # Ganymede + [False, False, [None, None]] # Callisto + ] + + for row in range(4): for col in range(2): - assert abs( - result_matrix[row][col] - result_matrix_expect[row][ - col]) < TOL, \ - """ERROR: is_phenomena() test two doesn't match""" - - """ Unit test weather the software detects the right phenomea or not - Matrix: - col 0: test case identifier - col 1: Epoch to be tested - col 2/3: row/col-index of expected 'True' - All other entries are expected to be 'False'!""" - test_set = [["IO_OCC_START_2021_01_17_00_55_11", - Epoch(2021, 1, 17.0383217592593), 0, 0], - ["IO_ECC_START_2021_02_12_14_19_14", - Epoch(2021, 2, 12.5966898148148), 0, 1], - ["EU_OCC_START_2021_10_02_13_04_19", - Epoch(2021, 10, 2.54466435185185), 1, 0], - ["EU_ECC_START_2021_02_13_14_26_18", - Epoch(2021, 2, 13.6015972222222), 1, 1], - ["GA_OCC_START_2021_03_29_00_43_46", - Epoch(2021, 3, 29.0303935185185), 2, 0], - ["GA_ECC_START_2021_02_06_16_53_50", - Epoch(2021, 2, 6.70405092592593), 2, 1], - ["CA_OCC_START_2021_03_09_13_26_47", - Epoch(2021, 3, 9.5602662037037), 3, 0], - ["CA_ECC_START_2021_04_28_13_32_36", - Epoch(2021, 4, 28.5643055555556), 3, 1], - ["IO_OCC_END_2021_02_14_11_20_01", - Epoch(2021, 2, 14.4722337962963), 0, 0], - ["IO_ECC_END_2021_10_09_14_44_31", - Epoch(2021, 10, 9.61424768518519), 0, 1], - ["EU_OCC_END_2021_03_07_02_14_12", - Epoch(2021, 3, 7.09319444444444), 1, 0], - ["EU_ECC_END_2021_10_06_07_12_45", - Epoch(2021, 10, 6.30052083333333), 1, 1], - ["GA_OCC_END_2021_12_18_23_58_55", - Epoch(2021, 12, 18.9992476851852), 2, 0], - ["GA_ECC_END_2021_12_04_20_34_04", - Epoch(2021, 12, 4.85699074074074), 2, 1], - ["CA_OCC_END_2021_11_15_07_29_43", - Epoch(2021, 11, 15.3123032407407), 3, 0], - ["CA_ECC_END_2021_08_24_00_58_49", - Epoch(2021, 8, 24.0408449074074), 3, 1] - ] - - for test_label in range(15): - result = JupiterMoons.is_phenomena(test_set[test_label][1]) - for column in range(1): - for row in range(3): - if column == test_set[test_label][3] and row == \ - test_set[test_label][2]: - assert result[test_set[test_label][2]][ - test_set[test_label][3]], \ - """ERROR: existing phenomena is not detected """ + assert result_matrix[row][col] == result_matrix_expect[row][col], \ + f"ERROR: Row {row}, col {col} mismatch on 2021-02-12!" + assert result_matrix[row][2] == result_matrix_expect[row][2], \ + f"ERROR: Row {row}, col 2 mismatch on 2021-02-12!" + + + test_set = [ + ["IO_OCC_START_2021_01_17_00_55_11", + Epoch(2021, 1, 17.0383217592593), 0, 0], + ["IO_ECC_START_2021_02_12_14_19_14", + Epoch(2021, 2, 12.5966898148148), 0, 1], + ["EU_OCC_START_2021_10_02_13_04_19", + Epoch(2021, 10, 2.54466435185185), 1, 0], + ["EU_ECC_START_2021_02_13_14_26_18", + Epoch(2021, 2, 13.6015972222222), 1, 1], + ["GA_OCC_START_2021_03_29_00_43_46", + Epoch(2021, 3, 29.0303935185185), 2, 0], + ["GA_ECC_START_2021_02_06_16_53_50", + Epoch(2021, 2, 6.70405092592593), 2, 1], + ["CA_OCC_START_2021_03_09_13_26_47", + Epoch(2021, 3, 9.5602662037037), 3, 0], + ["CA_ECC_START_2021_04_28_13_32_36", + Epoch(2021, 4, 28.5643055555556), 3, 1], + ["IO_OCC_END_2021_02_14_11_20_01", + Epoch(2021, 2, 14.4722337962963), 0, 0], + ["IO_ECC_END_2021_10_09_14_44_31", + Epoch(2021, 10, 9.61424768518519), 0, 1], + ["EU_OCC_END_2021_03_07_02_14_12", + Epoch(2021, 3, 7.09319444444444), 1, 0], + ["EU_ECC_END_2021_10_06_07_12_45", + Epoch(2021, 10, 6.30052083333333), 1, 1], + ["GA_OCC_END_2021_12_18_23_58_55", + Epoch(2021, 12, 18.9992476851852), 2, 0], + ["GA_ECC_END_2021_12_04_20_34_04", + Epoch(2021, 12, 4.85699074074074), 2, 1], + ["CA_OCC_END_2021_11_15_07_29_43", + Epoch(2021, 11, 15.3123032407407), 3, 0], + ["CA_ECC_END_2021_08_24_00_58_49", + Epoch(2021, 8, 24.0408449074074), 3, 1] + ] + + + for label, epoch_val, expected_row, expected_col in test_set: + result = JupiterMoons.is_phenomena(epoch_val) + + for row in range(4): + for col in range(2): + if row == expected_row and col == expected_col: + assert result[row][col] is True, \ + f"ERROR in {label}: expected row={row}, col={col} to be True" else: - assert not result[row][column], \ - """ERROR: non existing phenomena is detected""" + assert result[row][col] is False, \ + f"ERROR in {label}: row={row}, col={col} should be False" + + for row in range(4): + if result[row][0]: + assert result[row][2][0] is not None, \ + f"ERROR in {label}: row={row} Earth_Superior_Conjunction should not be None" + else: + assert result[row][2][0] is None, \ + f"ERROR in {label}: row={row} Earth_Superior_Conjunction should be None" + + if result[row][1]: + assert result[row][2][1] is not None, \ + f"ERROR in {label}: row={row} sun_Superior_Conjunction should not be None" + else: + assert result[row][2][1] is None, \ + f"ERROR in {label}: row={row} sun_Superior_Conjunction should be None"