From 9fc14f6e3e50fae3aa81be91d707b26ff7df0816 Mon Sep 17 00:00:00 2001 From: Stephanie Merritt Date: Thu, 9 May 2024 16:49:06 +0000 Subject: [PATCH 1/3] Adding error handling, missing filters. --- src/adler/dataclasses/AdlerPlanetoid.py | 28 ++++++++-- .../adler/dataclasses/test_AdlerPlanetoid.py | 52 ++++++++++++------- 2 files changed, 59 insertions(+), 21 deletions(-) diff --git a/src/adler/dataclasses/AdlerPlanetoid.py b/src/adler/dataclasses/AdlerPlanetoid.py index 8b03781..2b1d6a3 100644 --- a/src/adler/dataclasses/AdlerPlanetoid.py +++ b/src/adler/dataclasses/AdlerPlanetoid.py @@ -86,6 +86,12 @@ def construct_from_SQL( cls, ssObjectId, filter_list, date_range, sql_filename=sql_filename, schema=schema ) + if len(observations_by_filter) == 0: + raise Exception("No observations found for this object in the given filter(s). Check SSOID and try again.") + + # redo the filter list based on the available filters in observations_by_filter + filter_list = [obs_object.filter_name for obs_object in observations_by_filter] + mpcorb = cls.populate_MPCORB(cls, ssObjectId, sql_filename=sql_filename, schema=schema) ssobject = cls.populate_SSObject( cls, ssObjectId, filter_list, sql_filename=sql_filename, schema=schema @@ -122,6 +128,13 @@ def construct_from_RSP( observations_by_filter = cls.populate_observations( cls, ssObjectId, filter_list, date_range, service=service ) + + if len(observations_by_filter) == 0: + raise Exception("No observations found for this object in the given filter(s). Check SSOID and try again.") + + # redo the filter list based on the available filters in observations_by_filter + filter_list = [obs_object.filter_name for obs_object in observations_by_filter] + mpcorb = cls.populate_MPCORB(cls, ssObjectId, service=service) ssobject = cls.populate_SSObject(cls, ssObjectId, filter_list, service=service) @@ -185,9 +198,12 @@ def populate_observations( data_table = get_data_table(observations_sql_query, service=service, sql_filename=sql_filename) - observations_by_filter.append( - Observations.construct_from_data_table(ssObjectId, filter_name, data_table) - ) + if len(data_table) == 0: + print("WARNING: No observations found in {} filter for this object. Skipping this filter.".format(filter_name)) + else: + observations_by_filter.append( + Observations.construct_from_data_table(ssObjectId, filter_name, data_table) + ) return observations_by_filter @@ -228,6 +244,9 @@ def populate_MPCORB(self, ssObjectId, service=None, sql_filename=None, schema="d data_table = get_data_table(MPCORB_sql_query, service=service, sql_filename=sql_filename) + if len(data_table) == 0: + raise Exception("No MPCORB data for this object could be found for this SSObjectId.") + return MPCORB.construct_from_data_table(ssObjectId, data_table) def populate_SSObject( @@ -282,6 +301,9 @@ def populate_SSObject( data_table = get_data_table(SSObject_sql_query, service=service, sql_filename=sql_filename) + if len(data_table) == 0: + raise Exception("No SSObject data for this object could be found for this SSObjectId.") + return SSObject.construct_from_data_table(ssObjectId, filter_list, data_table) def observations_in_filter(self, filter_name): diff --git a/tests/adler/dataclasses/test_AdlerPlanetoid.py b/tests/adler/dataclasses/test_AdlerPlanetoid.py index a011540..6c978c6 100644 --- a/tests/adler/dataclasses/test_AdlerPlanetoid.py +++ b/tests/adler/dataclasses/test_AdlerPlanetoid.py @@ -11,13 +11,13 @@ def test_construct_from_SQL(): - test_planetoid = AdlerPlanetoid.construct_from_SQL(ssoid, test_db_path) + test_planetoid = AdlerPlanetoid.construct_from_SQL(ssoid, test_db_path, filter_list=["u", "g", "r", "i", "z", "y"]) # testing just a few values here to ensure correct setup: these objects have their own unit tests assert test_planetoid.MPCORB.mpcH == 19.8799991607666 assert test_planetoid.SSObject.discoverySubmissionDate == 60218.0 assert_almost_equal( - test_planetoid.observations_by_filter[1].mag, + test_planetoid.observations_by_filter[0].mag, [ 21.33099937, 22.67099953, @@ -31,10 +31,10 @@ def test_construct_from_SQL(): ], ) - # did we pick up all the filters? - assert len(test_planetoid.observations_by_filter) == 6 - assert len(test_planetoid.SSObject.filter_dependent_values) == 6 - assert test_planetoid.filter_list == ["u", "g", "r", "i", "z", "y"] + # did we pick up all the filters? note we ask for ugrizy but u and y are unpopulated in DP0.3, so the code should eliminate them + assert len(test_planetoid.observations_by_filter) == 4 + assert len(test_planetoid.SSObject.filter_dependent_values) == 4 + assert test_planetoid.filter_list == ["g", "r", "i", "z"] # checking the date range to ensure it's the default assert test_planetoid.date_range == [60000.0, 67300.0] @@ -100,12 +100,10 @@ def test_observations_in_filter(): test_planetoid = AdlerPlanetoid.construct_from_SQL(ssoid, test_db_path) # Python dataclasses create an __eq__ for you so object-to-object comparison just works, isn't that nice? - assert test_planetoid.observations_in_filter("u") == test_planetoid.observations_by_filter[0] - assert test_planetoid.observations_in_filter("g") == test_planetoid.observations_by_filter[1] - assert test_planetoid.observations_in_filter("r") == test_planetoid.observations_by_filter[2] - assert test_planetoid.observations_in_filter("i") == test_planetoid.observations_by_filter[3] - assert test_planetoid.observations_in_filter("z") == test_planetoid.observations_by_filter[4] - assert test_planetoid.observations_in_filter("y") == test_planetoid.observations_by_filter[5] + assert test_planetoid.observations_in_filter("g") == test_planetoid.observations_by_filter[0] + assert test_planetoid.observations_in_filter("r") == test_planetoid.observations_by_filter[1] + assert test_planetoid.observations_in_filter("i") == test_planetoid.observations_by_filter[2] + assert test_planetoid.observations_in_filter("z") == test_planetoid.observations_by_filter[3] with pytest.raises(ValueError) as error_info_1: test_planetoid.observations_in_filter("f") @@ -116,14 +114,32 @@ def test_observations_in_filter(): def test_SSObject_in_filter(): test_planetoid = AdlerPlanetoid.construct_from_SQL(ssoid, test_db_path) - assert test_planetoid.SSObject_in_filter("u") == test_planetoid.SSObject.filter_dependent_values[0] - assert test_planetoid.SSObject_in_filter("g") == test_planetoid.SSObject.filter_dependent_values[1] - assert test_planetoid.SSObject_in_filter("r") == test_planetoid.SSObject.filter_dependent_values[2] - assert test_planetoid.SSObject_in_filter("i") == test_planetoid.SSObject.filter_dependent_values[3] - assert test_planetoid.SSObject_in_filter("z") == test_planetoid.SSObject.filter_dependent_values[4] - assert test_planetoid.SSObject_in_filter("y") == test_planetoid.SSObject.filter_dependent_values[5] + assert test_planetoid.SSObject_in_filter("g") == test_planetoid.SSObject.filter_dependent_values[0] + assert test_planetoid.SSObject_in_filter("r") == test_planetoid.SSObject.filter_dependent_values[1] + assert test_planetoid.SSObject_in_filter("i") == test_planetoid.SSObject.filter_dependent_values[2] + assert test_planetoid.SSObject_in_filter("z") == test_planetoid.SSObject.filter_dependent_values[3] with pytest.raises(ValueError) as error_info_1: test_planetoid.SSObject_in_filter("f") assert error_info_1.value.args[0] == "Filter f is not in AdlerPlanetoid.filter_list." + + +def test_no_observations(): + with pytest.raises(Exception) as error_info: + test_planetoid = AdlerPlanetoid.construct_from_SQL(826857066833589477, test_db_path) + + assert error_info.value.args[0] == "No observations found for this object in the given filter(s). Check SSOID and try again." + + +def test_for_warnings(capsys): + + test_planetoid = AdlerPlanetoid.construct_from_SQL(ssoid, test_db_path, filter_list=["u", "g"]) + captured = capsys.readouterr() + + expected = ("WARNING: No observations found in u filter for this object. Skipping this filter.\n" + + "WARNING: n unpopulated in MPCORB table for this object. Storing NaN instead.\n" + + "WARNING: uncertaintyParameter unpopulated in MPCORB table for this object. Storing NaN instead.\n") + + assert captured.out == expected + \ No newline at end of file From ad9a4f775ea7be97c06120850c817dc4745d726b Mon Sep 17 00:00:00 2001 From: Steph Merritt Date: Thu, 9 May 2024 17:50:16 +0100 Subject: [PATCH 2/3] Linting. --- src/adler/dataclasses/AdlerPlanetoid.py | 16 ++++++++++++---- .../adler/dataclasses/test_AdlerPlanetoid.py | 19 ++++++++++++------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/adler/dataclasses/AdlerPlanetoid.py b/src/adler/dataclasses/AdlerPlanetoid.py index 2b1d6a3..7d0e381 100644 --- a/src/adler/dataclasses/AdlerPlanetoid.py +++ b/src/adler/dataclasses/AdlerPlanetoid.py @@ -87,7 +87,9 @@ def construct_from_SQL( ) if len(observations_by_filter) == 0: - raise Exception("No observations found for this object in the given filter(s). Check SSOID and try again.") + raise Exception( + "No observations found for this object in the given filter(s). Check SSOID and try again." + ) # redo the filter list based on the available filters in observations_by_filter filter_list = [obs_object.filter_name for obs_object in observations_by_filter] @@ -130,11 +132,13 @@ def construct_from_RSP( ) if len(observations_by_filter) == 0: - raise Exception("No observations found for this object in the given filter(s). Check SSOID and try again.") + raise Exception( + "No observations found for this object in the given filter(s). Check SSOID and try again." + ) # redo the filter list based on the available filters in observations_by_filter filter_list = [obs_object.filter_name for obs_object in observations_by_filter] - + mpcorb = cls.populate_MPCORB(cls, ssObjectId, service=service) ssobject = cls.populate_SSObject(cls, ssObjectId, filter_list, service=service) @@ -199,7 +203,11 @@ def populate_observations( data_table = get_data_table(observations_sql_query, service=service, sql_filename=sql_filename) if len(data_table) == 0: - print("WARNING: No observations found in {} filter for this object. Skipping this filter.".format(filter_name)) + print( + "WARNING: No observations found in {} filter for this object. Skipping this filter.".format( + filter_name + ) + ) else: observations_by_filter.append( Observations.construct_from_data_table(ssObjectId, filter_name, data_table) diff --git a/tests/adler/dataclasses/test_AdlerPlanetoid.py b/tests/adler/dataclasses/test_AdlerPlanetoid.py index 6c978c6..b72ea15 100644 --- a/tests/adler/dataclasses/test_AdlerPlanetoid.py +++ b/tests/adler/dataclasses/test_AdlerPlanetoid.py @@ -11,7 +11,9 @@ def test_construct_from_SQL(): - test_planetoid = AdlerPlanetoid.construct_from_SQL(ssoid, test_db_path, filter_list=["u", "g", "r", "i", "z", "y"]) + test_planetoid = AdlerPlanetoid.construct_from_SQL( + ssoid, test_db_path, filter_list=["u", "g", "r", "i", "z", "y"] + ) # testing just a few values here to ensure correct setup: these objects have their own unit tests assert test_planetoid.MPCORB.mpcH == 19.8799991607666 @@ -129,17 +131,20 @@ def test_no_observations(): with pytest.raises(Exception) as error_info: test_planetoid = AdlerPlanetoid.construct_from_SQL(826857066833589477, test_db_path) - assert error_info.value.args[0] == "No observations found for this object in the given filter(s). Check SSOID and try again." + assert ( + error_info.value.args[0] + == "No observations found for this object in the given filter(s). Check SSOID and try again." + ) def test_for_warnings(capsys): - test_planetoid = AdlerPlanetoid.construct_from_SQL(ssoid, test_db_path, filter_list=["u", "g"]) captured = capsys.readouterr() - expected = ("WARNING: No observations found in u filter for this object. Skipping this filter.\n" - + "WARNING: n unpopulated in MPCORB table for this object. Storing NaN instead.\n" - + "WARNING: uncertaintyParameter unpopulated in MPCORB table for this object. Storing NaN instead.\n") + expected = ( + "WARNING: No observations found in u filter for this object. Skipping this filter.\n" + + "WARNING: n unpopulated in MPCORB table for this object. Storing NaN instead.\n" + + "WARNING: uncertaintyParameter unpopulated in MPCORB table for this object. Storing NaN instead.\n" + ) assert captured.out == expected - \ No newline at end of file From 0a2fb2c46c0c05e9453239ae3b5f159182176631 Mon Sep 17 00:00:00 2001 From: Steph Merritt Date: Thu, 9 May 2024 17:59:51 +0100 Subject: [PATCH 3/3] Extra unit test. --- .../adler/dataclasses/test_AdlerPlanetoid.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/adler/dataclasses/test_AdlerPlanetoid.py b/tests/adler/dataclasses/test_AdlerPlanetoid.py index b72ea15..3ac451d 100644 --- a/tests/adler/dataclasses/test_AdlerPlanetoid.py +++ b/tests/adler/dataclasses/test_AdlerPlanetoid.py @@ -148,3 +148,23 @@ def test_for_warnings(capsys): ) assert captured.out == expected + + +def test_failed_SQL_queries(): + test_planetoid = AdlerPlanetoid.construct_from_SQL( + ssoid, test_db_path, filter_list=["u", "g", "r", "i", "z", "y"] + ) + + with pytest.raises(Exception) as error_info_1: + test_planetoid.populate_MPCORB("826857066833589477", sql_filename=test_db_path, schema="") + + assert error_info_1.value.args[0] == "No MPCORB data for this object could be found for this SSObjectId." + + with pytest.raises(Exception) as error_info_2: + test_planetoid.populate_SSObject( + "826857066833589477", filter_list=["u"], sql_filename=test_db_path, schema="" + ) + + assert ( + error_info_2.value.args[0] == "No SSObject data for this object could be found for this SSObjectId." + )