88from pathlib import Path
99
1010import numpy as np
11+ from astropy import units as u
1112from astropy .coordinates import ICRS , BarycentricTrueEcliptic , Galactic
1213from astropy .io import fits
14+ from astropy .nddata import block_reduce
1315from astropy_healpix import (
1416 HEALPix ,
1517 level_to_nside ,
@@ -215,7 +217,30 @@ def reproject_to_hips(
215217 cen_world = wcs_in .pixel_to_world (cen_x , cen_y )
216218 cor_world = wcs_in .pixel_to_world (cor_x , cor_y )
217219
218- radius = cor_world .separation (cen_world ).max () * 2
220+ separations = cor_world .separation (cen_world )
221+
222+ if np .any (np .isnan (separations )):
223+
224+ # At least one of the corners is outside of the region of validity of
225+ # the WCS, so we use a different approach where we randomly sample a
226+ # number of positions in the image and then check the maximum
227+ # separation between any pair of points.
228+
229+ n_ran = 1000
230+ ran_x = np .random .uniform (- 0.5 , nx - 0.5 , n_ran )
231+ ran_y = np .random .uniform (- 0.5 , nx - 0.5 , n_ran )
232+
233+ ran_world = wcs_in .pixel_to_world (ran_x , ran_y )
234+
235+ separations = ran_world [:, None ].separation (ran_world [None , :])
236+
237+ max_separation = np .nanmax (separations )
238+
239+ else :
240+
241+ max_separation = separations .max ()
242+
243+ radius = 1.5 * max_separation
219244
220245 # TODO: in future if astropy-healpix implements polygon searches, we could
221246 # use that instead
@@ -225,9 +250,10 @@ def reproject_to_hips(
225250 nside = level_to_nside (level )
226251 hp = HEALPix (nside = nside , order = "nested" , frame = frame )
227252
228- # indices = hp.cone_search_skycoord(cen_world, radius=radius)
229-
230- indices = np .arange (hp .npix )
253+ if radius > 120 * u .deg :
254+ indices = np .arange (hp .npix )
255+ else :
256+ indices = hp .cone_search_skycoord (cen_world , radius = radius )
231257
232258 logger .info (f"Found { len (indices )} tiles (at most) to generate at level { level } " )
233259
@@ -310,76 +336,82 @@ def process(index):
310336
311337 indices = np .array (generated_indices )
312338
313- # # Iterate over higher levels and compute lower resolution tiles
314- # for ilevel in range(level - 1, -1, -1):
315-
316- # # Find index of tiles to produce at lower-resolution levels
317- # indices = np.sort(np.unique(indices // 4))
318-
319- # make_tile_folders(level=ilevel, indices=indices, output_directory=output_directory)
320-
321- # for index in indices:
322-
323- # header = tile_header(level=ilevel, index=index, frame=frame, tile_size=tile_size)
324-
325- # if tile_format == "fits":
326- # array = np.zeros((tile_size, tile_size))
327- # elif tile_format == "png":
328- # array = np.zeros((tile_size, tile_size, 4), dtype=np.uint8)
329- # else:
330- # array = np.zeros((tile_size, tile_size, 3), dtype=np.uint8)
331-
332- # for subindex in range(4):
333-
334- # current_index = 4 * index + subindex
335- # subtile_filename = tile_filename(
336- # level=ilevel + 1,
337- # index=current_index,
338- # output_directory=output_directory,
339- # extension=EXTENSION[tile_format],
340- # )
341-
342- # if os.path.exists(subtile_filename):
343-
344- # if tile_format == "fits":
345- # data = block_reduce(fits.getdata(subtile_filename), 2, func=np.mean)
346- # else:
347- # data = block_reduce(
348- # np.array(Image.open(subtile_filename))[::-1], (2, 2, 1), func=np.mean
349- # )
350-
351- # if subindex == 0:
352- # array[256:, :256] = data
353- # elif subindex == 2:
354- # array[256:, 256:] = data
355- # elif subindex == 1:
356- # array[:256, :256] = data
357- # elif subindex == 3:
358- # array[:256, 256:] = data
359-
360- # if tile_format == "fits":
361- # fits.writeto(
362- # tile_filename(
363- # level=ilevel,
364- # index=index,
365- # output_directory=output_directory,
366- # extension=EXTENSION[tile_format],
367- # ),
368- # array,
369- # header,
370- # )
371- # else:
372- # image = as_transparent_rgb(array.transpose(2, 0, 1))
373- # if tile_format == "jpeg":
374- # image = image.convert("RGB")
375- # image.save(
376- # tile_filename(
377- # level=ilevel,
378- # index=index,
379- # output_directory=output_directory,
380- # extension=EXTENSION[tile_format],
381- # )
382- # )
339+ # Iterate over higher levels and compute lower resolution tiles
340+
341+ half_tile_size = tile_size // 2
342+
343+ for ilevel in range (level - 1 , - 1 , - 1 ):
344+
345+ # Find index of tiles to produce at lower-resolution levels
346+ indices = np .sort (np .unique (indices // 4 ))
347+
348+ make_tile_folders (level = ilevel , indices = indices , output_directory = output_directory )
349+
350+ for index in indices :
351+
352+ header = tile_header (level = ilevel , index = index , frame = frame , tile_size = tile_size )
353+
354+ if isinstance (header , tuple ):
355+ header = header [0 ]
356+
357+ if tile_format == "fits" :
358+ array = np .zeros ((tile_size , tile_size ))
359+ elif tile_format == "png" :
360+ array = np .zeros ((tile_size , tile_size , 4 ), dtype = np .uint8 )
361+ else :
362+ array = np .zeros ((tile_size , tile_size , 3 ), dtype = np .uint8 )
363+
364+ for subindex in range (4 ):
365+
366+ current_index = 4 * index + subindex
367+ subtile_filename = tile_filename (
368+ level = ilevel + 1 ,
369+ index = current_index ,
370+ output_directory = output_directory ,
371+ extension = EXTENSION [tile_format ],
372+ )
373+
374+ if os .path .exists (subtile_filename ):
375+
376+ if tile_format == "fits" :
377+ data = block_reduce (fits .getdata (subtile_filename ), 2 , func = np .mean )
378+ else :
379+ data = block_reduce (
380+ np .array (Image .open (subtile_filename ))[::- 1 ], (2 , 2 , 1 ), func = np .mean
381+ )
382+
383+ if subindex == 0 :
384+ array [half_tile_size :, :half_tile_size ] = data
385+ elif subindex == 2 :
386+ array [half_tile_size :, half_tile_size :] = data
387+ elif subindex == 1 :
388+ array [:half_tile_size , :half_tile_size ] = data
389+ elif subindex == 3 :
390+ array [:half_tile_size , half_tile_size :] = data
391+
392+ if tile_format == "fits" :
393+ fits .writeto (
394+ tile_filename (
395+ level = ilevel ,
396+ index = index ,
397+ output_directory = output_directory ,
398+ extension = EXTENSION [tile_format ],
399+ ),
400+ array ,
401+ header ,
402+ )
403+ else :
404+ image = as_transparent_rgb (array .transpose (2 , 0 , 1 ))
405+ if tile_format == "jpeg" :
406+ image = image .convert ("RGB" )
407+ image .save (
408+ tile_filename (
409+ level = ilevel ,
410+ index = index ,
411+ output_directory = output_directory ,
412+ extension = EXTENSION [tile_format ],
413+ )
414+ )
383415
384416 # Generate properties file
385417
0 commit comments