1414from astropy .units import UnitsError
1515from astropy .wcs .utils import _split_matrix
1616
17- from ndcube .utils .wcs import world_axis_to_pixel_axes
18-
1917try :
2018 # Import sunpy coordinates if available to register the frames and WCS functions with astropy
2119 import sunpy .coordinates # NOQA
@@ -486,47 +484,9 @@ def quantity(self):
486484 """Unitful representation of the NDCube data."""
487485 return u .Quantity (self .data , self .unit , copy = _NUMPY_COPY_IF_NEEDED )
488486
489- def _generate_independent_world_coords (self , pixel_corners , wcs , needed_axes , units ):
490- """
491- Generate world coordinates for independent axes.
492-
493- The idea is to workout only the specific grid that is needed for independent axes.
494- This speeds up the calculation of world coordinates and reduces memory usage.
495-
496- Parameters
497- ----------
498- pixel_corners : bool
499- If one needs pixel corners, otherwise pixel centers.
500- wcs : astropy.wcs.WCS
501- The WCS.
502- needed_axes : array-like
503- The required pixel axes.
504- units : bool
505- If units are needed.
506-
507- Returns
508- -------
509- array-like
510- The world coordinates.
511- """
512- needed_axes = np .array (needed_axes ).squeeze ()
513- if self .data .ndim in needed_axes :
514- required_axes = needed_axes - 1
515- else :
516- required_axes = needed_axes
517- lims = (- 0.5 , self .data .shape [::- 1 ][required_axes ] + 1 ) if pixel_corners else (0 , self .data .shape [::- 1 ][required_axes ])
518- indices = [np .arange (lims [0 ], lims [1 ]) if wanted else [0 ] for wanted in wcs .axis_correlation_matrix [required_axes ]]
519- world_coords = wcs .pixel_to_world_values (* indices )
520- if units :
521- world_coords = world_coords << u .Unit (wcs .world_axis_units [needed_axes ])
522- return world_coords
523-
524- def _generate_dependent_world_coords (self , pixel_corners , wcs , needed_axes , units ):
487+ def _generate_world_coords (self , pixel_corners , wcs , * , needed_axes , units = None ):
525488 """
526- Generate world coordinates for dependent axes.
527-
528- This will work out the exact grid that is needed for dependent axes
529- and can be time and memory consuming.
489+ Private method to generate world coordinates.
530490
531491 Parameters
532492 ----------
@@ -535,7 +495,7 @@ def _generate_dependent_world_coords(self, pixel_corners, wcs, needed_axes, unit
535495 wcs : astropy.wcs.WCS
536496 The WCS.
537497 needed_axes : array-like
538- The required pixel axes .
498+ The axes that are needed .
539499 units : bool
540500 If units are needed.
541501
@@ -573,6 +533,12 @@ def _generate_dependent_world_coords(self, pixel_corners, wcs, needed_axes, unit
573533 # And inject 0s for those coordinates
574534 for idx in non_corr_axes :
575535 sub_range .insert (idx , 0 )
536+ # If we are subsetting world axes, ignore any pixel axes which are not correlated with our requested world axis.
537+ if any (world_axis in needed_axes for world_axis in world_axes_indices ):
538+ needed_pixel_axes = wcs .axis_correlation_matrix [needed_axes ]
539+ unneeded_pixel_axes = np .argwhere (needed_pixel_axes .sum (axis = 0 ) == 0 )[:, 0 ]
540+ for idx in unneeded_pixel_axes :
541+ sub_range [idx ] = 0
576542 # Generate a grid of broadcastable pixel indices for all pixel dimensions
577543 grid = np .meshgrid (* sub_range , indexing = 'ij' )
578544 # Convert to world coordinates
@@ -592,41 +558,6 @@ def _generate_dependent_world_coords(self, pixel_corners, wcs, needed_axes, unit
592558 world_coords [i ] = coord << u .Unit (unit )
593559 return world_coords
594560
595- def _generate_world_coords (self , pixel_corners , wcs , * , needed_axes , units = None ):
596- """
597- Private method to generate world coordinates.
598-
599- Handles both dependent and independent axes.
600-
601- Parameters
602- ----------
603- pixel_corners : bool
604- If one needs pixel corners, otherwise pixel centers.
605- wcs : astropy.wcs.WCS
606- The WCS.
607- needed_axes : array-like
608- The axes that are needed.
609- units : bool
610- If units are needed.
611-
612- Returns
613- -------
614- array-like
615- The world coordinates.
616- """
617- axes_are_independent = []
618- pixel_axes = set ()
619- for world_axis in needed_axes :
620- pix_ax = world_axis_to_pixel_axes (world_axis , wcs .axis_correlation_matrix )
621- axes_are_independent .append (len (pix_ax ) == 1 )
622- pixel_axes = pixel_axes .union (set (pix_ax ))
623- pixel_axes = list (pixel_axes )
624- if all (axes_are_independent ) and len (pixel_axes ) == len (needed_axes ) and len (needed_axes ) != 0 :
625- world_coords = self ._generate_independent_world_coords (pixel_corners , wcs , needed_axes , units )
626- else :
627- world_coords = self ._generate_dependent_world_coords (pixel_corners , wcs , needed_axes , units )
628- return world_coords
629-
630561 @utils .cube .sanitize_wcs
631562 def axis_world_coords (self , * axes , pixel_corners = False , wcs = None ):
632563 # Docstring in NDCubeABC.
0 commit comments