Skip to content

Commit 2bbc231

Browse files
committed
CLI update
1 parent b520832 commit 2bbc231

File tree

1 file changed

+78
-16
lines changed

1 file changed

+78
-16
lines changed

Diff for: heracles/cli.py

+78-16
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from __future__ import annotations
2222

2323
import argparse
24+
import collections
2425
import gc
2526
import sys
2627
import textwrap
@@ -82,14 +83,14 @@ def _maps_alms_internal(
8283
*,
8384
maps_path: str | None = None,
8485
alms_path: str | None = None,
85-
config: str | None = None,
86+
config_path: str | None = None,
8687
parallel: bool = False,
8788
) -> None:
8889
"""
8990
Compute maps and/or alms from catalogues.
9091
"""
9192

92-
config_loaded = read_config(config)
93+
config = read_config(config_path)
9394

9495
if maps_path is not None:
9596
maps_out = heracles.io.MapFits(maps_path, clobber=True)
@@ -101,7 +102,7 @@ def _maps_alms_internal(
101102
else:
102103
alms_out = None
103104

104-
for catalog_config in config_loaded.catalogs:
105+
for catalog_config in config.catalogs:
105106
base_catalog = heracles.FitsCatalog(catalog_config.source)
106107
base_catalog.label = catalog_config.label
107108

@@ -114,7 +115,7 @@ def _maps_alms_internal(
114115
catalogs[selection.key] = base_catalog[selection.selection]
115116
visibilities[selection.key] = selection.visibility
116117

117-
fields = {key: config_loaded.fields[key] for key in catalog_config.fields}
118+
fields = {key: config.fields[key] for key in catalog_config.fields}
118119

119120
for key, catalog in catalogs.items():
120121
if visibilities[key] is not None:
@@ -166,21 +167,25 @@ def _maps_alms_internal(
166167

167168
def maps(
168169
path: str,
169-
config: str | None = None,
170+
config_path: str | None = None,
170171
parallel: bool = False,
171172
) -> None:
172173
"""map catalogues
173174
174175
Create maps from input catalogues.
175176
176177
"""
177-
_maps_alms_internal(maps_path=path, config=config, parallel=parallel)
178+
return _maps_alms_internal(
179+
maps_path=path,
180+
config_path=config_path,
181+
parallel=parallel,
182+
)
178183

179184

180185
def alms(
181186
path: str,
182-
maps: list[str] | None = None,
183-
config: str | None = None,
187+
maps: list[str],
188+
config_path: str | None = None,
184189
parallel: bool = False,
185190
) -> None:
186191
"""compute alms from catalogues or maps
@@ -189,12 +194,15 @@ def alms(
189194
190195
"""
191196
# if no maps are given, process directly from catalogues
192-
if maps is None:
193-
_maps_alms_internal(alms_path=path, config=config, parallel=parallel)
194-
return
197+
if not maps:
198+
return _maps_alms_internal(
199+
alms_path=path,
200+
config_path=config_path,
201+
parallel=parallel,
202+
)
195203

196204
# load configuration to get fields
197-
config_loaded = read_config(config)
205+
config = read_config(config_path)
198206

199207
# open output FITS
200208
alms_out = heracles.io.AlmFits(path, clobber=True)
@@ -208,12 +216,46 @@ def alms(
208216
data = heracles.io.MapFits(maps_path)
209217

210218
# transform this fits
211-
heracles.transform(config_loaded.fields, data, out=alms_out)
219+
heracles.transform(config.fields, data, out=alms_out)
212220

213221
# clean up before next iteration
214222
del data
215223

216224

225+
def spectra(
226+
path: str,
227+
alms: list[str],
228+
*,
229+
config_path: str | None = None,
230+
) -> None:
231+
"""compute angular power spectra
232+
233+
Compute angular power spectra from sets of alms.
234+
235+
"""
236+
237+
# load configuration to get requested spectra
238+
config = read_config(config_path)
239+
240+
# make sure two-point statistics are defined in config
241+
if not config.spectra:
242+
raise ValueError(f"{config_path}: no 'spectra' in config")
243+
244+
# lazy-load all input FITS into a combined mapping
245+
all_alms = collections.ChainMap({})
246+
for alms_path in alms:
247+
# quick check to see if file is readable
248+
with open(alms_path) as _fp:
249+
pass
250+
251+
# add new lazy-loaded FITS to the ChainMap
252+
# keys will be sorted in the order the files are passed
253+
all_alms = all_alms.new_child(heracles.io.AlmFits(alms_path, clobber=False))
254+
255+
# compute all spectra combinations
256+
spectra = {}
257+
258+
217259
def main() -> int:
218260
"""Main method of the `heracles` command.
219261
@@ -240,7 +282,12 @@ def add_command(func):
240282

241283
# common parser for all subcommands
242284
cmd_parser = argparse.ArgumentParser(add_help=False)
243-
cmd_parser.add_argument("-c", "--config", help="configuration file")
285+
cmd_parser.add_argument(
286+
"-c",
287+
"--config",
288+
help="configuration file",
289+
dest="config_path",
290+
)
244291

245292
# main parser for CLI invokation
246293
main_parser = argparse.ArgumentParser(
@@ -294,11 +341,26 @@ def add_command(func):
294341
help="output FITS file for alms",
295342
)
296343
alms_parser.add_argument(
297-
"--maps",
298-
action="append",
344+
"maps",
345+
nargs="*",
299346
help="transform pre-computed maps",
300347
)
301348

349+
###########
350+
# spectra #
351+
###########
352+
353+
spectra_parser = add_command(spectra)
354+
spectra_parser.add_argument(
355+
"path",
356+
help="output FITS file for spectra",
357+
)
358+
spectra_parser.add_argument(
359+
"alms",
360+
nargs="+",
361+
help="input FITS file(s) with sets of alms",
362+
)
363+
302364
#######
303365
# run #
304366
#######

0 commit comments

Comments
 (0)