-
Notifications
You must be signed in to change notification settings - Fork 5
/
generate_bitmaps.py
executable file
·106 lines (80 loc) · 3.19 KB
/
generate_bitmaps.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#! /usr/bin/env python3
"""Given a bunch of downloaded FITS images, combine them to emit JPEG images
and WTML files that can be view in WWT.
"""
import argparse
from astropy.io import fits
from astropy.visualization import AsymmetricPercentileInterval
from astropy.wcs import WCS
import numpy as np
import os.path
from PIL import Image
import sys
from wwt_data_formats import write_xml_doc
from wwt_data_formats.imageset import ImageSet
from wwt_data_formats.folder import Folder
# Hack to share data between the scripts
from download_contextual_imagery import TARGETS
def main():
ap = argparse.ArgumentParser(
description = 'Generate bitmap images'
)
ap.add_argument(
'indir',
help = 'The directory with the downloaded FITS files.'
)
ap.add_argument(
'outdir',
help = 'The directory in which to save the JPEG and WTML files.'
)
settings = ap.parse_args()
# Scan the input directory
all_surveys = set()
sources = {}
for basename in os.listdir(settings.indir):
source, survey = basename.replace('.fits', '').split('_', 1)
survey_to_path = sources.setdefault(source, {})
survey_to_path[survey] = os.path.join(settings.indir, basename)
all_surveys.add(survey)
if '2MASS-J' in all_surveys:
all_surveys = ['2MASS-K', '2MASS-H', '2MASS-J']
merge_name = '2MASS'
else:
all_surveys = sorted(all_surveys) # default
merge_name = all_surveys[0]
# Process away using our dumb algorithm
folder = Folder()
for source, survey_to_path in sources.items():
inputs = [survey_to_path.get(s) for s in all_surveys]
imgbase = f'{source}-{merge_name}.jpg'
template_path = inputs[0] # NB. we could make fewer assumptions here
hdulist = fits.open(template_path)
template_hdu = hdulist[0]
shape = template_hdu.shape
imgset = ImageSet()
imgset.set_position_from_wcs(template_hdu.header, shape[1], shape[0])
imgset.credits = 'Omitted! Shame!'
imgset.data_set_type = 'Sky'
imgset.description = f'{source} in {merge_name}'
imgset.file_type = '.jpg'
imgset.name = f'StarHunt-Context-{source}-{merge_name}'
imgset.url = os.path.join(settings.outdir, imgbase) # XXX not necessarily the right assumption
folder.children.append(imgset)
buffer = np.zeros(shape + (3,))
# Load the images. For 2MASS, it turns out that we should stretch
# each channel independently, so that's what we do.
stretch = AsymmetricPercentileInterval(0.5, 98)
for idx, path in enumerate(inputs):
if path is None:
continue
hdu = fits.open(path)[0]
assert hdu.shape == shape
buffer[::-1,...,idx] = stretch(hdu.data) # flip vertically: FITS convention => bitmap
buffer = (255 * buffer).astype(np.uint8)
# Write out the results
img = Image.fromarray(buffer)
img.save(os.path.join(settings.outdir, imgbase))
with open(os.path.join(settings.outdir, f'{merge_name}.wtml'), 'wt') as f:
write_xml_doc(folder.to_xml(), dest_stream=f)
if __name__ == '__main__':
main()