diff --git a/stellarphot/gui_tools/comparison_functions.py b/stellarphot/gui_tools/comparison_functions.py index 5e7ca8e9..4bea8cc9 100644 --- a/stellarphot/gui_tools/comparison_functions.py +++ b/stellarphot/gui_tools/comparison_functions.py @@ -8,6 +8,7 @@ from astropy.coordinates import SkyCoord from astropy.coordinates.name_resolve import NameResolveError from astropy.table import Table +from ipyautoui.custom import FileChooser try: from astrowidgets import ImageWidget @@ -22,7 +23,7 @@ SourceLocationSettings, ui_generator, ) -from stellarphot.settings.custom_widgets import SettingWithTitle +from stellarphot.settings.custom_widgets import SettingWithTitle, Spinner from stellarphot.settings.fits_opener import FitsOpener from stellarphot.utils.comparison_utils import ( crossmatch_APASS2VSX, @@ -305,12 +306,20 @@ def _init(self): self.ccd = self.fits_file.ccd self.fits_file.load_in_image_widget(self.iw) + spinner = Spinner(message="Loading variable/comparison stars") + legend = self._legend_spinner_box.children[0] + spinner.start() + self._legend_spinner_box.children = [spinner] + self.help_stuff.selected_index = 1 + self.vsx = set_up(self.ccd) apass, vsx_apass_angle, targets_apass_angle = crossmatch_APASS2VSX( self.ccd, self.targets_from_file, self.vsx ) + self._legend_spinner_box.children = [legend] + apass_good_coord, good_stars = mag_scale( self.target_mag, apass, @@ -379,11 +388,10 @@ def _set_object(self): self.ccd.shape[0] / 2, self.ccd.shape[1] / 2 ) - def _set_file(self, change): # noqa: ARG002 + def _save_source_location_file(self): """ - Widget callbacks need to accept a change argument, even if not used. + Save the source location file. """ - self._init() # Save the initial source list if there is a file name for it and if the target # coordinates are known. The target coordinates are needed to generate the # source list table. @@ -393,10 +401,29 @@ def _set_file(self, change): # noqa: ARG002 ): self._save_aperture_to_file(None) + def _set_file(self, change): # noqa: ARG002 + """ + Widget callbacks need to accept a change argument, even if not used. + """ + self._init() + self._save_source_location_file() + + def _set_target_file(self, change): + """ + Set the target file. + """ + input_source_list_name = change["new"] + self.targets_from_file = SourceListData.read(input_source_list_name) + # Only call init if a file has been chosen + if self._file_chooser.file_chooser.value != ".": + self._init() + self._save_source_location_file() + def _make_observers(self): self._show_labels_button.observe(self._show_label_button_handler, names="value") self._save_var_info.on_click(self._save_variables_to_file) self._file_chooser.file_chooser.observe(self._set_file, names="_value") + self._choose_input_source_list.observe(self._set_target_file, names="_value") def _save_variables_to_file(self, button=None, filename=""): # noqa: ARG002 """ @@ -542,7 +569,13 @@ def _viewer(self): ) self.source_locations.savebuttonbar.fns_onsave_add_action(self.save) - self.help_stuff = ipw.Accordion(children=[header, legend]) + + # Put the legend in a box whose children can be changed to a + # spinner while loading. + self._legend_spinner_box = ipw.VBox() + self._legend_spinner_box.children = [legend] + + self.help_stuff = ipw.Accordion(children=[header, self._legend_spinner_box]) self.help_stuff.titles = ["Help", "Legend"] box = ipw.VBox() inner_box = ipw.HBox() @@ -552,10 +585,17 @@ def _viewer(self): self.object_name, self.source_and_title, ] - inner_box.children = [iw, source_legend_box] # legend] + inner_box.children = [iw, source_legend_box] + + # Add a file chooser for an input source list + self._choose_input_source_list = FileChooser( + filter_pattern="*.ecsv", + ) + self._choose_input_source_list.title = "OPTIONAL: Choose input source list" box.children = [ self._file_chooser.file_chooser, + self._choose_input_source_list, inner_box, controls, ] diff --git a/stellarphot/gui_tools/tests/test_comparison_functions.py b/stellarphot/gui_tools/tests/test_comparison_functions.py index 69cad7b4..8b572ac4 100644 --- a/stellarphot/gui_tools/tests/test_comparison_functions.py +++ b/stellarphot/gui_tools/tests/test_comparison_functions.py @@ -1,3 +1,4 @@ +import gzip import os import re import warnings @@ -14,6 +15,7 @@ from astropy.wcs import WCS from astropy.wcs.wcs import FITSFixedWarning +from stellarphot import SourceListData from stellarphot.gui_tools import comparison_functions as cf from stellarphot.settings import PhotometryWorkingDirSettings @@ -145,7 +147,7 @@ def test_loading_second_image_succeeds(tmp_path): file_name = "TIC.fits" path = tmp_path / file_name ccd.write(path, overwrite=True) - print(path) + with warnings.catch_warnings(): # Ignore the warning about the WCS having non-standard keywords (the SIP # distortion parameters). @@ -182,7 +184,7 @@ def test_loading_second_image_succeeds(tmp_path): # Also make sure this is where the viewer is actually centered # Get the value of the HTML widget that shows the coordinates view_coord_text = comparison_widget.iw.children[1].value - print(view_coord_text) + # Extract the coordinates from the text match = re.search( r"RA: +(\d+:\d+:[.\d]+), +DEC: +([+\d]+:\d+:[.\d]+)", view_coord_text @@ -194,3 +196,46 @@ def test_loading_second_image_succeeds(tmp_path): # close to the target coordinates, where by close I mean "less than the # diagonal width of the frame". assert viewer_coord.separation(wasp_coord) < 1 * u.degree + + +@pytest.mark.remote_data +def test_loading_input_source_list(tmp_path): + # Test that we can load a source list from a file + comparison_widget = cf.ComparisonViewer() + compressed_input_source_list = get_pkg_data_filename( + "tests/data/TIC-402828941-source-list-input.ecsv.gz", package="stellarphot" + ) + with gzip.open(compressed_input_source_list, "rb") as f: + source_list_content = f.read() + input_source_list = tmp_path / "input-sources.ecsv" + input_source_list.write_text(source_list_content.decode("utf-8")) + ccd = CCDData.read( + get_pkg_data_filename( + "tests/data/TIC_402828941-tiny.fit.bz2", package="stellarphot" + ) + ) + file_name = "TIC.fits" + path = tmp_path / file_name + ccd.write(path, overwrite=True) + + with warnings.catch_warnings(): + # Ignore the warning about the WCS having non-standard keywords (the SIP + # distortion parameters). + warnings.filterwarnings( + "ignore", + message="Some non-standard WCS keywords were excluded", + category=AstropyWarning, + ) + comparison_widget._file_chooser.file_chooser.value = path + + comparison_widget._choose_input_source_list.value = input_source_list + + # Check that the number of tess targets matches the number in the + # input source list + + comp_viewer_sources = SourceListData.read("source_locations.ecsv") + input_sources = SourceListData.read(input_source_list) + + num_tess = np.sum(comp_viewer_sources["marker name"] == "TESS Targets") + + assert num_tess == len(input_sources) diff --git a/stellarphot/tests/data/TIC-402828941-source-list-input.ecsv.gz b/stellarphot/tests/data/TIC-402828941-source-list-input.ecsv.gz new file mode 100644 index 00000000..8950ad7a Binary files /dev/null and b/stellarphot/tests/data/TIC-402828941-source-list-input.ecsv.gz differ