forked from SETI/rms-hst-pipeline
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDownloadTargetFiles.py
More file actions
155 lines (123 loc) · 4.64 KB
/
DownloadTargetFiles.py
File metadata and controls
155 lines (123 loc) · 4.64 KB
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import os
import os.path
from typing import Iterable, List, Optional, Tuple, cast
from astropy.table import Table
from astropy.table.row import Row
from astroquery.mast import Observations
from pdart.astroquery.Utils import (
filter_table,
get_table_with_retries,
ymd_tuple_to_mjd,
)
_YMD = Tuple[int, int, int]
_ACCEPTED_INSTRUMENTS: str = "IJLNOSUVWXYZ"
"""
We currently only handle products from a limited set of
instruments. These are the first letters of their 'obs_id's.
"""
ACCEPTED_SUFFIXES: List[str] = [
"SHF",
"SHM",
"SPT",
]
"""
For now, we limit the types of the products to those with these
suffixes.
"""
def _is_accepted_instrument_product_row(row: Row) -> bool:
"""
We currently only handle products from a limited set of
instruments.
"""
def instrument_key(id: str) -> str:
"""
Return the first letter of the obs_id, which tells which
instrument made the observation.
"""
return id[0].upper()
return instrument_key(row["obs_id"]) in _ACCEPTED_INSTRUMENTS
def _is_accepted_product_type_product_row(row: Row) -> bool:
"""
We currently only handle products from a limited set of
instruments.
"""
desc = str(row["productSubGroupDescription"])
return desc.upper() in ACCEPTED_SUFFIXES
class MastSlice(object):
"""
A slice in time of the MAST database.
Look in test_Astroquery.py for a current list of the columns
returned for observations and products.
"""
def __init__(
self, start_date: _YMD, end_date: _YMD, proposal_id: Optional[int] = None
) -> None:
"""
Given a start and an end date expressed as ymd triples,
download a slice of the MAST database and express it as an
object.
"""
self.start_date = ymd_tuple_to_mjd(start_date)
self.end_date = ymd_tuple_to_mjd(end_date)
def mast_call() -> Table:
if proposal_id is not None:
return Observations.query_criteria(
dataproduct_type=["image"],
dataRights="PUBLIC",
obs_collection=["HST"],
proposal_id=str(proposal_id),
t_obs_release=(self.start_date, self.end_date),
mtFlag=True,
)
else:
return Observations.query_criteria(
dataproduct_type=["image"],
dataRights="PUBLIC",
obs_collection=["HST"],
t_obs_release=(self.start_date, self.end_date),
mtFlag=True,
)
self.observations_table = get_table_with_retries(mast_call, 1)
self.proposal_ids: Optional[List[int]] = None
def __str__(self) -> str:
return f"MastSlice(julian day [{self.start_date}, {self.end_date}])"
def get_proposal_ids(self) -> List[int]:
if self.proposal_ids is None:
result = [int(id) for id in self.observations_table["proposal_id"]]
self.proposal_ids = sorted(list(set(result)))
return self.proposal_ids
def get_products(self) -> Table:
result = Observations.get_product_list(self.observations_table)
result = filter_table(_is_accepted_instrument_product_row, result)
result = filter_table(_is_accepted_product_type_product_row, result)
return result
def to_product_set(self) -> "ProductSet":
return ProductSet(self.get_products())
def download_products(self, products_table: Table, download_dir: str) -> None:
if len(products_table) > 0:
Observations.download_products(
products_table, mrp_only=False, download_dir=download_dir
)
def products_size(table: Table) -> int:
return sum(cast(Iterable[int], table["size"]))
class ProductSet(object):
"""
A downloadable collection of MAST products.
"""
def __init__(self, table: Table) -> None:
self.table = table
def product_count(self) -> int:
return len(self.table)
def download_size(self) -> int:
return sum(cast(Iterable[int], self.table["size"]))
def download(self, download_dir: str) -> None:
if len(self.table) > 0:
Observations.download_products(self.table, download_dir=download_dir)
if __name__ == "__main__":
working_dir = "/Volumes/CassiniArchives/TargetFiles"
slice = MastSlice((1900, 1, 1), (2025, 1, 1))
product_set = slice.to_product_set()
print(f"{product_set.product_count()} products, size {product_set.download_size()}")
# if not os.path.isdir(working_dir):
# os.makedirs(working_dir)
# product_set.download(working_dir)