From 8c831c1c1632427f874ba8f28dae1220e481aa84 Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Wed, 25 Aug 2021 23:35:43 +0100 Subject: [PATCH 01/10] Added initial dev docs on linking --- docs/dev/index.rst | 1 + docs/dev/links.rst | 160 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 docs/dev/links.rst diff --git a/docs/dev/index.rst b/docs/dev/index.rst index be4720b8da..e99828ab2a 100644 --- a/docs/dev/index.rst +++ b/docs/dev/index.rst @@ -11,3 +11,4 @@ Here is some documentation specific for developers. infrastructure ui_description specviz_selection + links diff --git a/docs/dev/links.rst b/docs/dev/links.rst new file mode 100644 index 0000000000..e4a8d89d10 --- /dev/null +++ b/docs/dev/links.rst @@ -0,0 +1,160 @@ +*************************** +Linking of datasets in glue +*************************** + +.. note:: The glue documentation includes a page about + `linking `_ but + it is somewhat out of date - the present page should be considered a + more up-to-date guide with a focus on links useful to jdaviz. + +The 'why' of linking +==================== + +First, why is linking needed in the first place? Linking in glue is simply a way +to describe the relationship between datasets, with two main goals: to know how +to overplot datasets, and to know how to apply a subset defined in one dataset +(such as a spectral range) to another dataset. Having linking means being able +to show e.g. multiple spectra in the same plot, or multiple images that are +aligned in the same image viewer, or contours on top of an image. + +There are various ways of setting up links in glue, but the two main ways that +have been discussed and used in jdaviz are linking by pixel coordinates, and +linking by world coordinates. + +Linking by pixel coordinates with an identity link +================================================== + +Linking by pixel coordinates with an identity link with a means that glue +considers that the datasets' pixel grids are lined up at that the origins of the +datasets overlap. This means that if one has two images, with shape (32,32) and +(128,128), the (0,0) pixels will overlap, and the (32,32) dataset will be lined +up with the first (32,32) pixels of the larger dataset, starting at the origin. +This is equivalent to the **Match image** mode in DS9. + +An example of setting up an identity link in pixel coordinates between two +datasets with equal dimensionality would look like:: + + from glue.core.link_helpers import LinkSame + + pix_ids_1 = data1.pixel_component_ids + pix_ids_2 = data2.pixel_component_ids + + for i in range(data1.ndim): + data_collection.add_link(LinkSame(pix_ids_1[i], pix_ids_2[i])) + +This can also be used to link for example the two spatial dimensions of a +collapsed cube with the original cube, as done in the `cube collapse +functionality `_ +in jdaviz. This linking would then allow e.g. the collapsed dataset to be shown +as contours on top of the original sliced cube. + +This is by far the fastest way of linking, but it does rely on the datasets +being exactly lined up pixel-wise. This approach can likely be used in specific +parsers where it is known that the datasets are on the same grid. + +Linking by world coordinates +============================ + +Using LinkSame +-------------- + +There are two main ways of linking by world coordinates. The first is to do +something similar to how pixel coordinates are linked:: + + from glue.core.link_helpers import LinkSame + + world_ids_1 = data1.world_component_ids + world_ids_2 = data2.world_component_ids + + for i in range(data1.ndim): + data_collection.add_link(LinkSame(world_ids_1[i], world_ids_2[i])) + +or see the `following example `_ +from jdaviz. + +However, this kind of linking is not generally robust because it relies on the +world coordinates *actually* being the same between the two datasets - so it +would fail for two images where one image was in equatorial coordinates and the +other one was in galactic coordinates, because LinkSame would mean that RA was +the *same* as Galactic longitude, which it is not. Likewise, this would result +in e.g. wavelength in one dataset being equated with frequency in another. The +only place this kind of linking could be used is within parsers for specific +data where it is known with certainty that two world coordinates are the same. +But in general, wherever possible I think we should phase out any use of +LinkSame for world coordinates from jdaviz. + +Using WCSLink +------------- + +A more robust approach for linking datasets by world coordinates is to use the +``WCSLink`` class. Given two datasets, and a list of pixel component IDs to link +in each dataset, this class will set up links between the pixel components by +internally representing the chain of WCS transformations required. As an +example:: + + from glue.plugins.wcs_autolinking.wcs_autolinking import WCSLink + + link = WCSLink(data1=data1, data2=data2, + cids1=data1.pixel_component_ids, cids2=data2.pixel_component_ids) + + data_collection.add_link(link) + +will link all pixel axes between the two datasets, taking into account the WCS +of ``data1`` and ``data2``. + +Note that this should work with any APE 14-compliant WCS, so could link for +example a FITS WCS to a GWCS instance. + +Speeding up WCS links +===================== + +In some cases, doing the full WCS transformations can be slow, and may not be +necessary if the two datasets are close to each other or overlap significantly. +For the best performance, it is possible to approximate the WCSLink by a simple +affine transformation between the datasets. This can be done with the +``as_affine_link`` method:: + + link = WCSLink(data1=data1, data2=data2, + cids1=data1.pixel_component_ids, + cids2=data2.pixel_component_ids) + + fast_link = link.as_affine_transform() + + data_collection.add_link(fast_link) + +The ``as_affine_link`` method takes a ``tolerance`` argument which defaults +to 1 pixel - if no approximation can be found that transforms all positions in +the image to within that tolerance, an error of type ``NoAffineApproximation`` +is returned (this exception is defined in +``glue.plugins.wcs_autolinking.wcs_autolinking``). + +I think whenever we use WCSLink in jdaviz we should then use an affine +approximation whenever one can be calculated, as for visualization purposes it +should be good enough (as a side note, I think DS9 uses a similar approach). + +Speeding up adding links to the data collection +=============================================== + +Each time a link, dataset, or component/attribute is added to the data +collection in glue, the link tree is recalculated. This can be prevented by +using the +`WCSLink.delay_link_manager_update `_ +context manager. Use this around any block that adds multiple datasets to the +data collection, components/attributes to datasets, or links to the data +collection, e.g.:: + + with data_collection.delay_link_manager_update(): + for i in range(10): + data_collection.append(Data(...)) data_collection.add_link(...) + +Mixing link types +================= + +Glue can handle many different link types in a same session, so for instance if +one had three datasets, two of the datasets could be linked by a ``WCSLink`` +while two other datasets could be linked by pixel coordinates. However, the same +two datasets should not be linked both by ``WCSLink`` and pixel coordinates at +the same time as which link takes precedence is not defined. + + + From 5620efc8e9aba22e92253b63cdea6c8d7884b85c Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Thu, 26 Aug 2021 13:03:44 +0100 Subject: [PATCH 02/10] Added section about set_links --- docs/dev/links.rst | 63 ++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 21 deletions(-) diff --git a/docs/dev/links.rst b/docs/dev/links.rst index e4a8d89d10..b171663e52 100644 --- a/docs/dev/links.rst +++ b/docs/dev/links.rst @@ -87,10 +87,10 @@ Using WCSLink ------------- A more robust approach for linking datasets by world coordinates is to use the -``WCSLink`` class. Given two datasets, and a list of pixel component IDs to link -in each dataset, this class will set up links between the pixel components by -internally representing the chain of WCS transformations required. As an -example:: +:class:`~glue.plugins.wcs_autolinker.wcs_autolinker.WCSLink` class. Given two +datasets, and a list of pixel component IDs to link in each dataset, this class +will set up links between the pixel components by internally representing the +chain of WCS transformations required. As an example:: from glue.plugins.wcs_autolinking.wcs_autolinking import WCSLink @@ -110,9 +110,10 @@ Speeding up WCS links In some cases, doing the full WCS transformations can be slow, and may not be necessary if the two datasets are close to each other or overlap significantly. -For the best performance, it is possible to approximate the WCSLink by a simple -affine transformation between the datasets. This can be done with the -``as_affine_link`` method:: +For the best performance, it is possible to approximate the +:class:`~glue.plugins.wcs_autolinker.wcs_autolinker.WCSLink` by a simple affine +transformation between the datasets. This can be done with the +:meth:`~glue.plugins.wcs_autolinker.wcs_autolinker.WCSLink.as_affine_link` method:: link = WCSLink(data1=data1, data2=data2, cids1=data1.pixel_component_ids, @@ -122,15 +123,16 @@ affine transformation between the datasets. This can be done with the data_collection.add_link(fast_link) -The ``as_affine_link`` method takes a ``tolerance`` argument which defaults -to 1 pixel - if no approximation can be found that transforms all positions in -the image to within that tolerance, an error of type ``NoAffineApproximation`` -is returned (this exception is defined in -``glue.plugins.wcs_autolinking.wcs_autolinking``). +The :meth:`~glue.plugins.wcs_autolinker.wcs_autolinker.WCSLink.as_affine_link` +method takes a ``tolerance`` argument which defaults to 1 pixel - if no +approximation can be found that transforms all positions in the image to within +that tolerance, an error of type ``NoAffineApproximation`` is returned (this +exception is defined in :mod:`glue.plugins.wcs_autolinking.wcs_autolinking`). -I think whenever we use WCSLink in jdaviz we should then use an affine -approximation whenever one can be calculated, as for visualization purposes it -should be good enough (as a side note, I think DS9 uses a similar approach). +I think whenever we use :class:`~glue.plugins.wcs_autolinker.wcs_autolinker.WCSLink` +in jdaviz we should then use an affine approximation whenever one can be +calculated, as for visualization purposes it should be good enough (as a side +note, I think DS9 uses a similar approach). Speeding up adding links to the data collection =============================================== @@ -138,23 +140,42 @@ Speeding up adding links to the data collection Each time a link, dataset, or component/attribute is added to the data collection in glue, the link tree is recalculated. This can be prevented by using the -`WCSLink.delay_link_manager_update `_ +:meth:`~glue.core.data_collection.DataCollection.delay_link_manager_update` context manager. Use this around any block that adds multiple datasets to the data collection, components/attributes to datasets, or links to the data collection, e.g.:: with data_collection.delay_link_manager_update(): for i in range(10): - data_collection.append(Data(...)) data_collection.add_link(...) + data_collection.append(Data(...)) + data_collection.add_link(...) + +Setting all links in one go +=========================== + +If you want to prepare and set all links in one go, discarding any previous links, +you can make use of the :meth:`~glue.core.data_collection.DataCollectionn.set_links` +method, which takes a list of links:: + + data_collection.set_links([link1, link2, link3]) + +Note that for now it can still be beneficial to use this inside the +:meth:`~glue.core.data_collection.DataCollection.delay_link_manager_update` +context manager mentioned in the previous section. + +This method is ideal if you want to e.g. switch between using pixel and WCS links +as it will discard any existing links before adding the new ones. Mixing link types ================= Glue can handle many different link types in a same session, so for instance if -one had three datasets, two of the datasets could be linked by a ``WCSLink`` -while two other datasets could be linked by pixel coordinates. However, the same -two datasets should not be linked both by ``WCSLink`` and pixel coordinates at -the same time as which link takes precedence is not defined. +one had three datasets, two of the datasets could be linked by a +:class:`~glue.plugins.wcs_autolinker.wcs_autolinker.WCSLink` while two other +datasets could be linked by pixel coordinates. However, the same two datasets +should not be linked both by :class:`~glue.plugins.wcs_autolinker.wcs_autolinker.WCSLink` +and pixel coordinates at the same time as which link takes precedence is not +defined. From 5de4239af0f7d4efabb97535e5318a16001ce8ca Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Mon, 30 Aug 2021 20:23:22 +0100 Subject: [PATCH 03/10] Apply suggestions from code review Co-authored-by: P. L. Lim <2090236+pllim@users.noreply.github.com> --- docs/dev/links.rst | 94 ++++++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 41 deletions(-) diff --git a/docs/dev/links.rst b/docs/dev/links.rst index b171663e52..ab1aea5e7a 100644 --- a/docs/dev/links.rst +++ b/docs/dev/links.rst @@ -4,32 +4,34 @@ Linking of datasets in glue .. note:: The glue documentation includes a page about `linking `_ but - it is somewhat out of date - the present page should be considered a - more up-to-date guide with a focus on links useful to jdaviz. + the present page should be considered a + more up-to-date guide with a focus on links useful to Jdaviz. The 'why' of linking ==================== -First, why is linking needed in the first place? Linking in glue is simply a way +Why is linking needed in the first place? Linking in glue is a way to describe the relationship between datasets, with two main goals: to know how to overplot datasets, and to know how to apply a subset defined in one dataset (such as a spectral range) to another dataset. Having linking means being able -to show e.g. multiple spectra in the same plot, or multiple images that are +to show, say, multiple spectra in the same plot, or multiple images that are aligned in the same image viewer, or contours on top of an image. There are various ways of setting up links in glue, but the two main ways that -have been discussed and used in jdaviz are linking by pixel coordinates, and -linking by world coordinates. +have been discussed and used in Jdaviz are linking by pixel coordinates, and +linking by world coordinates (WCS). + +.. _link_by_pixel: Linking by pixel coordinates with an identity link ================================================== -Linking by pixel coordinates with an identity link with a means that glue -considers that the datasets' pixel grids are lined up at that the origins of the +Linking by pixel coordinates with an identity link means that glue +considers that the datasets' pixel grids are lined up at where the origins of the datasets overlap. This means that if one has two images, with shape (32,32) and (128,128), the (0,0) pixels will overlap, and the (32,32) dataset will be lined up with the first (32,32) pixels of the larger dataset, starting at the origin. -This is equivalent to the **Match image** mode in DS9. +This is equivalent to the "match image" mode in DS9. An example of setting up an identity link in pixel coordinates between two datasets with equal dimensionality would look like:: @@ -42,24 +44,27 @@ datasets with equal dimensionality would look like:: for i in range(data1.ndim): data_collection.add_link(LinkSame(pix_ids_1[i], pix_ids_2[i])) -This can also be used to link for example the two spatial dimensions of a +This can also be used to link, for example, the two spatial dimensions of a collapsed cube with the original cube, as done in the `cube collapse functionality `_ -in jdaviz. This linking would then allow e.g. the collapsed dataset to be shown +in Jdaviz. This linking would then allow the collapsed dataset to be shown as contours on top of the original sliced cube. This is by far the fastest way of linking, but it does rely on the datasets being exactly lined up pixel-wise. This approach can likely be used in specific parsers where it is known that the datasets are on the same grid. -Linking by world coordinates -============================ +.. _link_by_wcs: + +Linking by WCS +============== + +There are two main ways of linking by world coordinates, as follow. -Using LinkSame --------------- +Using LinkSame (not recommended) +-------------------------------- -There are two main ways of linking by world coordinates. The first is to do -something similar to how pixel coordinates are linked:: +The first is to do something similar to how pixel coordinates are linked in :ref:`link_by_pixel`:: from glue.core.link_helpers import LinkSame @@ -70,21 +75,21 @@ something similar to how pixel coordinates are linked:: data_collection.add_link(LinkSame(world_ids_1[i], world_ids_2[i])) or see the `following example `_ -from jdaviz. +from Jdaviz. However, this kind of linking is not generally robust because it relies on the world coordinates *actually* being the same between the two datasets - so it would fail for two images where one image was in equatorial coordinates and the other one was in galactic coordinates, because LinkSame would mean that RA was the *same* as Galactic longitude, which it is not. Likewise, this would result -in e.g. wavelength in one dataset being equated with frequency in another. The +in, say, wavelength in one dataset being equated wrongly with frequency in another. The only place this kind of linking could be used is within parsers for specific -data where it is known with certainty that two world coordinates are the same. -But in general, wherever possible I think we should phase out any use of -LinkSame for world coordinates from jdaviz. +data where it is known with certainty that two world coordinate systems are the same. -Using WCSLink -------------- +In general, one should avoid using LinkSame for world coordinates in Jdaviz. + +Using WCSLink (recommended) +--------------------------- A more robust approach for linking datasets by world coordinates is to use the :class:`~glue.plugins.wcs_autolinker.wcs_autolinker.WCSLink` class. Given two @@ -95,15 +100,15 @@ chain of WCS transformations required. As an example:: from glue.plugins.wcs_autolinking.wcs_autolinking import WCSLink link = WCSLink(data1=data1, data2=data2, - cids1=data1.pixel_component_ids, cids2=data2.pixel_component_ids) + cids1=data1.pixel_component_ids, cids2=data2.pixel_component_ids) data_collection.add_link(link) will link all pixel axes between the two datasets, taking into account the WCS of ``data1`` and ``data2``. -Note that this should work with any APE 14-compliant WCS, so could link for -example a FITS WCS to a GWCS instance. +Note that this should work with any `APE 14 `_-compliant WCS, so it could link +both a FITS WCS to a GWCS instance, and vice versa. Speeding up WCS links ===================== @@ -129,16 +134,18 @@ approximation can be found that transforms all positions in the image to within that tolerance, an error of type ``NoAffineApproximation`` is returned (this exception is defined in :mod:`glue.plugins.wcs_autolinking.wcs_autolinking`). -I think whenever we use :class:`~glue.plugins.wcs_autolinker.wcs_autolinker.WCSLink` -in jdaviz we should then use an affine approximation whenever one can be -calculated, as for visualization purposes it should be good enough (as a side -note, I think DS9 uses a similar approach). +It is recommended that whenever :class:`~glue.plugins.wcs_autolinker.wcs_autolinker.WCSLink` is used +in Jdaviz, affine approximation should be used whenever possible. +For visualization purposes, it should be good enough for most cases. +DS9 uses a similar approach. + +.. _need_for_link_speed: Speeding up adding links to the data collection =============================================== Each time a link, dataset, or component/attribute is added to the data -collection in glue, the link tree is recalculated. This can be prevented by +collection in glue, the link tree is recalculated. Unnecessary recalculations can be prevented by using the :meth:`~glue.core.data_collection.DataCollection.delay_link_manager_update` context manager. Use this around any block that adds multiple datasets to the @@ -150,6 +157,8 @@ collection, e.g.:: data_collection.append(Data(...)) data_collection.add_link(...) +See `pull request 762 `_ for a more concrete example. + Setting all links in one go =========================== @@ -159,23 +168,26 @@ method, which takes a list of links:: data_collection.set_links([link1, link2, link3]) -Note that for now it can still be beneficial to use this inside the +It is recommended to use this inside the :meth:`~glue.core.data_collection.DataCollection.delay_link_manager_update` -context manager mentioned in the previous section. +context manager, as mentioned in :ref:`need_for_link_speed`. -This method is ideal if you want to e.g. switch between using pixel and WCS links +This method is ideal if you want to, say, switch between using pixel and WCS links as it will discard any existing links before adding the new ones. +This is necessary because the same two datasets cannot have both +pixel and WCS links, as explained in :ref:`link_mixing`. + +.. _link_mixing: + Mixing link types ================= -Glue can handle many different link types in a same session, so for instance if -one had three datasets, two of the datasets could be linked by a +Glue can handle many different link types in a same session. For instance, if +there are three datasets, two of the datasets could be linked by a :class:`~glue.plugins.wcs_autolinker.wcs_autolinker.WCSLink` while two other datasets could be linked by pixel coordinates. However, the same two datasets should not be linked both by :class:`~glue.plugins.wcs_autolinker.wcs_autolinker.WCSLink` -and pixel coordinates at the same time as which link takes precedence is not -defined. - - +and pixel coordinates at the same time, as which link takes precedence is not +defined, resulting in ambiguous behavior. From 42b253e80be62373ec6b94af1656792017955da0 Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Thu, 2 Sep 2021 20:22:15 +0100 Subject: [PATCH 04/10] Fix glue intersphinx links --- docs/conf.py | 3 +++ docs/dev/links.rst | 18 ++++++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index d21a493283..e2a776d83d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -184,3 +184,6 @@ # dtype, target = line.split(None, 1) # target = target.strip() # nitpick_ignore.append((dtype, six.u(target))) + +intersphinx_mapping['glue'] = ('http://docs.glueviz.org/en/stable/', None) + diff --git a/docs/dev/links.rst b/docs/dev/links.rst index ab1aea5e7a..f5ea31605a 100644 --- a/docs/dev/links.rst +++ b/docs/dev/links.rst @@ -92,7 +92,7 @@ Using WCSLink (recommended) --------------------------- A more robust approach for linking datasets by world coordinates is to use the -:class:`~glue.plugins.wcs_autolinker.wcs_autolinker.WCSLink` class. Given two +:class:`~glue.plugins.wcs_autolinking.wcs_autolinking.WCSLink` class. Given two datasets, and a list of pixel component IDs to link in each dataset, this class will set up links between the pixel components by internally representing the chain of WCS transformations required. As an example:: @@ -116,9 +116,9 @@ Speeding up WCS links In some cases, doing the full WCS transformations can be slow, and may not be necessary if the two datasets are close to each other or overlap significantly. For the best performance, it is possible to approximate the -:class:`~glue.plugins.wcs_autolinker.wcs_autolinker.WCSLink` by a simple affine +:class:`~glue.plugins.wcs_autolinking.wcs_autolinking.WCSLink` by a simple affine transformation between the datasets. This can be done with the -:meth:`~glue.plugins.wcs_autolinker.wcs_autolinker.WCSLink.as_affine_link` method:: +:meth:`~glue.plugins.wcs_autolinking.wcs_autolinking.WCSLink.as_affine_link` method:: link = WCSLink(data1=data1, data2=data2, cids1=data1.pixel_component_ids, @@ -128,13 +128,12 @@ transformation between the datasets. This can be done with the data_collection.add_link(fast_link) -The :meth:`~glue.plugins.wcs_autolinker.wcs_autolinker.WCSLink.as_affine_link` +The :meth:`~glue.plugins.wcs_autolinking.wcs_autolinking.WCSLink.as_affine_link` method takes a ``tolerance`` argument which defaults to 1 pixel - if no approximation can be found that transforms all positions in the image to within -that tolerance, an error of type ``NoAffineApproximation`` is returned (this -exception is defined in :mod:`glue.plugins.wcs_autolinking.wcs_autolinking`). +that tolerance, an error of type :class:`~glue.plugins.wcs_autolinking.wcs_autolinking.NoAffineApproximation` is returned. -It is recommended that whenever :class:`~glue.plugins.wcs_autolinker.wcs_autolinker.WCSLink` is used +It is recommended that whenever :class:`~glue.plugins.wcs_autolinking.wcs_autolinking.WCSLink` is used in Jdaviz, affine approximation should be used whenever possible. For visualization purposes, it should be good enough for most cases. DS9 uses a similar approach. @@ -185,9 +184,8 @@ Mixing link types Glue can handle many different link types in a same session. For instance, if there are three datasets, two of the datasets could be linked by a -:class:`~glue.plugins.wcs_autolinker.wcs_autolinker.WCSLink` while two other +:class:`~glue.plugins.wcs_autolinking.wcs_autolinking.WCSLink` while two other datasets could be linked by pixel coordinates. However, the same two datasets -should not be linked both by :class:`~glue.plugins.wcs_autolinker.wcs_autolinker.WCSLink` +should not be linked both by :class:`~glue.plugins.wcs_autolinking.wcs_autolinking.WCSLink` and pixel coordinates at the same time, as which link takes precedence is not defined, resulting in ambiguous behavior. - From cbb45ae6ada1532b0fd209947a269c55d48c6a7b Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Thu, 2 Sep 2021 20:27:16 +0100 Subject: [PATCH 05/10] Apply suggestions from code review Co-authored-by: P. L. Lim <2090236+pllim@users.noreply.github.com> --- docs/dev/links.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/dev/links.rst b/docs/dev/links.rst index f5ea31605a..9f3b31d86f 100644 --- a/docs/dev/links.rst +++ b/docs/dev/links.rst @@ -78,7 +78,7 @@ or see the `following example `_ for a more concrete example. -Setting all links in one go -=========================== +Setting or Resetting all links in one go +======================================== If you want to prepare and set all links in one go, discarding any previous links, you can make use of the :meth:`~glue.core.data_collection.DataCollectionn.set_links` From bc1d01d7c4f8c083cded58bb006804f79a3807ef Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Thu, 2 Sep 2021 21:04:22 +0100 Subject: [PATCH 06/10] Avoid repeated calls to add_link --- docs/dev/links.rst | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/dev/links.rst b/docs/dev/links.rst index 9f3b31d86f..ddaadd03e0 100644 --- a/docs/dev/links.rst +++ b/docs/dev/links.rst @@ -34,15 +34,18 @@ up with the first (32,32) pixels of the larger dataset, starting at the origin. This is equivalent to the "match image" mode in DS9. An example of setting up an identity link in pixel coordinates between two -datasets with equal dimensionality would look like:: +n-dimensional datasets where n is the same for both datasets would look like:: from glue.core.link_helpers import LinkSame pix_ids_1 = data1.pixel_component_ids pix_ids_2 = data2.pixel_component_ids + links = [] for i in range(data1.ndim): - data_collection.add_link(LinkSame(pix_ids_1[i], pix_ids_2[i])) + links.append(LinkSame(pix_ids_1[i], pix_ids_2[i])) + + data_collection.add_link(links) This can also be used to link, for example, the two spatial dimensions of a collapsed cube with the original cube, as done in the `cube collapse @@ -71,8 +74,11 @@ The first is to do something similar to how pixel coordinates are linked in :ref world_ids_1 = data1.world_component_ids world_ids_2 = data2.world_component_ids + links = [] for i in range(data1.ndim): - data_collection.add_link(LinkSame(world_ids_1[i], world_ids_2[i])) + links.append(LinkSame(world_ids_1[i], world_ids_2[i])) + + data_collection.add_link(links) or see the `following example `_ from Jdaviz. From c56cd2a594867a55bd1f8a425b94a57e5f559c75 Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Thu, 2 Sep 2021 21:29:15 +0100 Subject: [PATCH 07/10] Added note about pixel linking --- docs/dev/links.rst | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/dev/links.rst b/docs/dev/links.rst index ddaadd03e0..f9f718cac8 100644 --- a/docs/dev/links.rst +++ b/docs/dev/links.rst @@ -54,9 +54,15 @@ in Jdaviz. This linking would then allow the collapsed dataset to be shown as contours on top of the original sliced cube. This is by far the fastest way of linking, but it does rely on the datasets -being exactly lined up pixel-wise. This approach can likely be used in specific +being lined up pixel-wise. This approach can be used in specific parsers where it is known that the datasets are on the same grid. +It is also possible to link all datasets using pixel links, but users will +need to be aware that this then means specific features (such as stars) in +different datasets will not line up when e.g. blinking, and making a selection +or region of a certain feature will not necessarily select the same feature +in another dataset. + .. _link_by_wcs: Linking by WCS From c22fb69daca59188fce6abe194c00304e96cd9ff Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Thu, 2 Sep 2021 21:31:29 +0100 Subject: [PATCH 08/10] Clarify wording of speeding up links --- docs/dev/links.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev/links.rst b/docs/dev/links.rst index f9f718cac8..2a9af6b8ae 100644 --- a/docs/dev/links.rst +++ b/docs/dev/links.rst @@ -126,7 +126,7 @@ Speeding up WCS links ===================== In some cases, doing the full WCS transformations can be slow, and may not be -necessary if the two datasets are close to each other or overlap significantly. +necessary if the two datasets are close to each other and have a similar WCS. For the best performance, it is possible to approximate the :class:`~glue.plugins.wcs_autolinking.wcs_autolinking.WCSLink` by a simple affine transformation between the datasets. This can be done with the From b51e1b317c90922f7d6743a94c95a014ae62e83e Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Thu, 2 Sep 2021 21:33:39 +0100 Subject: [PATCH 09/10] Whitespace --- docs/conf.py | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index e2a776d83d..b2c2589758 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -186,4 +186,3 @@ # nitpick_ignore.append((dtype, six.u(target))) intersphinx_mapping['glue'] = ('http://docs.glueviz.org/en/stable/', None) - From 6c7a4ff76e951bf0516a5796222cd0fc1c2687f3 Mon Sep 17 00:00:00 2001 From: "P. L. Lim" <2090236+pllim@users.noreply.github.com> Date: Thu, 2 Sep 2021 17:40:23 -0400 Subject: [PATCH 10/10] Minor edits --- docs/dev/links.rst | 60 +++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/docs/dev/links.rst b/docs/dev/links.rst index 2a9af6b8ae..199a0b8172 100644 --- a/docs/dev/links.rst +++ b/docs/dev/links.rst @@ -18,8 +18,8 @@ to show, say, multiple spectra in the same plot, or multiple images that are aligned in the same image viewer, or contours on top of an image. There are various ways of setting up links in glue, but the two main ways that -have been discussed and used in Jdaviz are linking by pixel coordinates, and -linking by world coordinates (WCS). +have been discussed and used in Jdaviz are linking by pixel coordinates and +by world coordinates (WCS). .. _link_by_pixel: @@ -59,7 +59,7 @@ parsers where it is known that the datasets are on the same grid. It is also possible to link all datasets using pixel links, but users will need to be aware that this then means specific features (such as stars) in -different datasets will not line up when e.g. blinking, and making a selection +different datasets will not line up when, e.g., blinking, and making a selection or region of a certain feature will not necessarily select the same feature in another dataset. @@ -68,7 +68,29 @@ in another dataset. Linking by WCS ============== -There are two main ways of linking by world coordinates, as follow. +There are two main ways of linking by WCS, as follow. + +Using WCSLink (recommended) +--------------------------- + +The more robust approach for linking datasets by WCS is to use the +:class:`~glue.plugins.wcs_autolinking.wcs_autolinking.WCSLink` class. Given two +datasets, and a list of pixel component IDs to link in each dataset, this class +will set up links between the pixel components by internally representing the +chain of WCS transformations required. As an example:: + + from glue.plugins.wcs_autolinking.wcs_autolinking import WCSLink + + link = WCSLink(data1=data1, data2=data2, + cids1=data1.pixel_component_ids, cids2=data2.pixel_component_ids) + + data_collection.add_link(link) + +The example above will link all pixel axes between the two datasets, taking into account the WCS +of ``data1`` and ``data2``. + +Note that this should work with any `APE 14 `_-compliant WCS, so it could link +both a FITS WCS to a GWCS instance, and vice versa. Using LinkSame (not recommended) -------------------------------- @@ -90,9 +112,9 @@ or see the `following example `_-compliant WCS, so it could link -both a FITS WCS to a GWCS instance, and vice versa. - Speeding up WCS links ===================== @@ -170,11 +170,11 @@ collection, e.g.:: See `pull request 762 `_ for a more concrete example. -Setting or Resetting all links in one go +Setting or resetting all links in one go ======================================== If you want to prepare and set all links in one go, discarding any previous links, -you can make use of the :meth:`~glue.core.data_collection.DataCollectionn.set_links` +you can make use of the :meth:`~glue.core.data_collection.DataCollection.set_links` method, which takes a list of links:: data_collection.set_links([link1, link2, link3])