Skip to content

Commit 3aee9b8

Browse files
committed
complated eso sdss heasarc modules
1 parent a341ebe commit 3aee9b8

File tree

22 files changed

+2250
-1464
lines changed

22 files changed

+2250
-1464
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@ A practical command-line interface (CLI) for selected [astroquery](https://astro
1616
- **ESASky**: Sky region visualization queries
1717
- **Gaia**: Cone search
1818
- **IRSA**: Infrared Science Archive queries
19-
- **IRSA Dust**: Infrared Science Archive Dust queries
20-
- **JPLHorizons**: JPL Horizons queries
19+
- **Heasarc**: HEASARC Archive queries
2120
- **JPLSBDB**: JPL Small-Body Database queries
2221
- **MAST**: Mikulski Archive for Space Telescopes queries
2322
- **NASA-ADS**: NASA Astrophysics Data System literature search and BibTeX retrieval, allows simple commands to search for "latest papers" or "highly cited reviews".
2423
- **NED**: NASA/IPAC Extragalactic Database name resolution
24+
- **NIST**: National Institute of Standards and Technology Atomic Spectra Database queries
25+
- **SDSS**: Sloan Digital Sky Survey queries
26+
- **ESO**: European Southern Observatory queries
2527
- **SIMBAD**: SIMBAD Astronomical Database basic query
2628
- **Splatalogue**: Molecular line queries
2729
- **VizieR**: VizieR Catalogue Database catalog search, basic query

astroquery_cli/__main__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from .main import cli
2+
3+
if __name__ == "__main__":
4+
cli()
3.83 KB
Binary file not shown.
4.17 KB
Binary file not shown.
3.28 KB
Binary file not shown.

astroquery_cli/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def load_default_lang():
5757
help=i18n._("Astroquery CLI"),
5858
invoke_without_command=True,
5959
no_args_is_help=False,
60-
add_completion=True,
60+
add_completion=False, # Set to False to remove global completion commands
6161
context_settings={"help_option_names": ["-h", "--help"]},
6262
)
6363

astroquery_cli/modules/esasky_cli.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ def esasky_callback(
103103
"EROSITA-EFEDS-MAIN",
104104
"EROSITA-EFEDS-HARD",
105105
"EUCLID-MER",
106-
"CHANDRA-SC21",
106+
"atnfpsr-SC21",
107107
"XMM-EPIC-STACK",
108108
"XMM-OM",
109109
"HCV",
@@ -228,7 +228,7 @@ def query_region_catalogs(ctx: typer.Context,
228228
catalogs: Optional[List[str]] = typer.Option(
229229
None,
230230
"--catalog",
231-
help=builtins._("Specify catalogs to query (e.g., 'XMM-Newton (XMM-SSC)', 'Chandra (CDA)'). Can be specified multiple times. Use 'object' command to see all available catalogs.")
231+
help=builtins._("Specify catalogs to query (e.g., 'XMM-Newton (XMM-SSC)', 'atnfpsr (CDA)'). Can be specified multiple times. Use 'object' command to see all available catalogs.")
232232
),
233233
output_file: Optional[str] = common_output_options["output_file"],
234234
output_format: Optional[str] = common_output_options["output_format"],

astroquery_cli/modules/heasarc_cli.py

Lines changed: 112 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,30 @@ def get_app():
2424
app = typer.Typer(
2525
name="heasarc",
2626
help=builtins._("Query the HEASARC database."),
27-
invoke_without_command=True,
28-
no_args_is_help=False
27+
invoke_without_command=True, # Allow invoking without a subcommand
28+
# no_args_is_help=True # Show help if no arguments are provided (handled manually below)
2929
)
3030

3131
@app.callback()
32+
@global_keyboard_interrupt_handler
3233
def heasarc_callback(
3334
ctx: typer.Context,
34-
debug: bool = typer.Option(
35+
# Moved query options to callback
36+
ra: Optional[float] = typer.Option(None, help=builtins._("Right Ascension in degrees.")),
37+
dec: Optional[float] = typer.Option(None, help=builtins._("Declination in degrees.")),
38+
radius: Optional[float] = typer.Option(None, help=builtins._("Search radius in degrees (for cone search).")),
39+
output_file: Optional[str] = common_output_options["output_file"],
40+
output_format: Optional[str] = common_output_options["output_format"],
41+
max_rows_display: int = typer.Option(
42+
25, "--max-rows-display", help=builtins._("Maximum number of rows to display. Use -1 for all rows.")
43+
),
44+
show_all_columns: bool = typer.Option(
45+
False, "--show-all-cols", help=builtins._("Show all columns in the output table.")
46+
),
47+
max_rows: int = typer.Option(
48+
100, "--max-rows", help=builtins._("Maximum number of rows to retrieve from the HEASARC database. Use -1 for all rows.")
49+
),
50+
enable_debug: bool = typer.Option(
3551
False,
3652
"-t",
3753
"--debug",
@@ -43,64 +59,84 @@ def heasarc_callback(
4359
"-v",
4460
"--verbose",
4561
help=_("Enable verbose output.")
46-
)
62+
),
4763
):
48-
setup_debug_context(ctx, debug, verbose)
49-
50-
if ctx.invoked_subcommand is None and \
51-
not any(arg in ["-h", "--help"] for arg in ctx.args):
52-
help_output_capture = StringIO()
53-
with redirect_stdout(help_output_capture):
54-
try:
55-
app(ctx.args + ["--help"])
56-
except SystemExit:
57-
pass
58-
full_help_text = help_output_capture.getvalue()
64+
setup_debug_context(ctx, enable_debug, verbose)
65+
debug(f"heasarc_callback: ctx.invoked_subcommand={ctx.invoked_subcommand}, ctx.args={ctx.args}")
66+
heasarc = Heasarc() # Instantiate Heasarc here for all operations
5967

60-
commands_match = re.search(r'╭─ Commands ─.*?(\n(?:│.*?\n)*)╰─.*─╯', full_help_text, re.DOTALL)
61-
if commands_match:
62-
commands_section = commands_match.group(0)
63-
filtered_commands_section = "\n".join([
64-
line for line in commands_section.splitlines() if "Usage:" not in line
65-
])
66-
console.print(filtered_commands_section)
67-
else:
68-
console.print(full_help_text)
69-
raise typer.Exit()
68+
# Check if a subcommand was invoked (e.g., 'list')
69+
if ctx.invoked_subcommand is not None:
70+
return # Let the subcommand handle its own logic
7071

71-
@app.command(name="query", help=builtins._("Perform a query on HEASARC."))
72+
@app.command(name="query", help=builtins._("Query a specific HEASARC mission. Use 'heasarc list' to see available missions."))
7273
@global_keyboard_interrupt_handler
73-
def query_heasarc(
74+
def query_heasarc_mission(
7475
ctx: typer.Context,
75-
mission: str = typer.Argument(..., help=builtins._("HEASARC mission name (e.g., 'chandra', 'xmm').")),
76+
mission: str = typer.Argument(..., help=builtins._("HEASARC mission name (e.g., 'atnfpsr').")),
7677
ra: Optional[float] = typer.Option(None, help=builtins._("Right Ascension in degrees.")),
7778
dec: Optional[float] = typer.Option(None, help=builtins._("Declination in degrees.")),
7879
radius: Optional[float] = typer.Option(None, help=builtins._("Search radius in degrees (for cone search).")),
7980
output_file: Optional[str] = common_output_options["output_file"],
8081
output_format: Optional[str] = common_output_options["output_format"],
8182
max_rows_display: int = typer.Option(
82-
25, help=builtins._("Maximum number of rows to display. Use -1 for all rows.")
83+
25, "--max-rows-display", help=builtins._("Maximum number of rows to display. Use -1 for all rows.")
8384
),
8485
show_all_columns: bool = typer.Option(
8586
False, "--show-all-cols", help=builtins._("Show all columns in the output table.")
8687
),
88+
max_rows: int = typer.Option(
89+
100, "--max-rows", help=builtins._("Maximum number of rows to retrieve from the HEASARC database. Use -1 for all rows.")
90+
),
8791
):
88-
if ctx.obj.get("DEBUG"):
89-
debug(f"query_heasarc - mission: {mission}, ra: {ra}, dec: {dec}, radius: {radius}")
92+
# Debug context is set up by the heasarc_callback
93+
heasarc = Heasarc() # Instantiate Heasarc here for all operations
9094

9195
console.print(f"[cyan]{_('Querying HEASARC mission: {mission}...').format(mission=mission)}[/cyan]")
9296

9397
try:
94-
heasarc = Heasarc()
95-
heasarc.mission = mission
98+
# Get the actual catalog name from the mission list
99+
catalogs = heasarc.list_catalogs()
100+
101+
catalog_name = None
102+
search_mission_upper = mission.strip().upper()
103+
104+
# Specific mapping for 'atnfpsr' to 'atnfpulsar'
105+
if search_mission_upper == 'ATNFPSR':
106+
catalog_name = 'atnfpulsar'
107+
else:
108+
for row in catalogs:
109+
# Use 'name' as the primary key for catalog/table name
110+
if 'name' in row and row['name'].strip().upper() == search_mission_upper:
111+
catalog_name = row['name']
112+
break
113+
# Fallback to 'Table' or 'CATALOG' if 'name' is not present or doesn't match
114+
elif 'Table' in row and row['Table'].strip().upper() == search_mission_upper:
115+
catalog_name = row['Table']
116+
break
117+
elif 'CATALOG' in row and row['CATALOG'].strip().upper() == search_mission_upper:
118+
catalog_name = row['CATALOG']
119+
break
120+
121+
if catalog_name is None:
122+
console.print(_(f"[red]Error: Mission '{mission}' not found in HEASARC catalogs. Use 'heasarc list' to see available missions.[/red]"))
123+
raise typer.Exit(code=1)
124+
125+
# Set maxrec for query
126+
maxrec_value = None if max_rows == -1 else max_rows
96127

97128
if ra is not None and dec is not None:
98129
if radius is None:
99130
console.print(_("[red]Error: --radius is required when --ra and --dec are provided for a cone search.[/red]"))
100131
raise typer.Exit(code=1)
101-
results = heasarc.query_region(ra=ra, dec=dec, radius=radius)
132+
adql_query = heasarc.query_region(ra=ra, dec=dec, radius=radius, catalog=catalog_name, get_query_payload=True, maxrec=maxrec_value)
133+
console.print(f"[debug] ADQL Query (cone): {adql_query}")
134+
results = heasarc.query_region(ra=ra, dec=dec, radius=radius, catalog=catalog_name, maxrec=maxrec_value)
102135
else:
103-
results = heasarc.query_object(mission) # Query all data for the mission
136+
# Use query_tap for all-sky queries with the correct catalog name
137+
adql_query_string = f"SELECT * FROM {catalog_name}"
138+
console.print(f"[debug] ADQL Query (all-sky): {adql_query_string}")
139+
results = heasarc.query_tap(query=adql_query_string, maxrec=maxrec_value)
104140

105141
if results and len(results) > 0:
106142
console.print(_("[green]Found {count} result(s) from HEASARC.[/green]").format(count=len(results)))
@@ -114,20 +150,52 @@ def query_heasarc(
114150
handle_astroquery_exception(ctx, e, _("HEASARC query"))
115151
raise typer.Exit(code=1)
116152

117-
@app.command(name="list-missions", help=builtins._("List available HEASARC missions."))
153+
@app.command(name="list", help=builtins._("List available HEASARC missions."))
118154
@global_keyboard_interrupt_handler
119-
def list_missions(ctx: typer.Context):
155+
def list_heasarc_missions(
156+
ctx: typer.Context,
157+
max_rows_display: int = typer.Option(
158+
25, "--max-rows-display", "--max-rows", help=builtins._("Maximum number of rows to display. Use -1 for all rows.")
159+
),
160+
show_all_columns: bool = typer.Option(
161+
False, "--show-all-cols", help=builtins._("Show all columns in the output table.")
162+
),
163+
prefix: Optional[str] = typer.Option(
164+
None, "--prefix", "-p", help=builtins._("Filter missions by a starting prefix (e.g., 'atnfpsr').")
165+
),
166+
):
167+
debug(f"list_heasarc_missions: max_rows_display={max_rows_display}, show_all_columns={show_all_columns}, prefix={prefix}")
168+
heasarc = Heasarc()
120169
console.print(f"[cyan]{_('Listing HEASARC missions...')}[/cyan]")
121170
try:
122-
missions = Heasarc.get_missions()
123-
if missions:
124-
console.print(_("[green]Available HEASARC Missions:[/green]"))
125-
for m in missions:
126-
console.print(f"- {m}")
171+
missions_table = heasarc.list_catalogs()
172+
173+
if prefix:
174+
original_count = len(missions_table)
175+
# Determine the correct column name for filtering
176+
mission_name_column = None
177+
if 'name' in missions_table.colnames:
178+
mission_name_column = 'name'
179+
elif 'Table' in missions_table.colnames:
180+
mission_name_column = 'Table'
181+
elif 'CATALOG' in missions_table.colnames:
182+
mission_name_column = 'CATALOG'
183+
184+
if mission_name_column:
185+
# Apply the filter using boolean indexing
186+
mask = [str(name).lower().startswith(prefix.lower()) for name in missions_table[mission_name_column]]
187+
missions_table = missions_table[mask]
188+
else:
189+
# If no suitable column is found, log a warning or handle appropriately
190+
debug("Could not find a suitable mission name column ('name', 'Table', or 'CATALOG') for filtering.")
191+
192+
console.print(_("[cyan]Filtered from {original_count} to {filtered_count} missions with prefix \"{prefix}\".[/cyan]").format(original_count=original_count, filtered_count=len(missions_table), prefix=prefix))
193+
194+
if missions_table:
195+
display_table(ctx, missions_table, title=_("Available HEASARC Missions"), max_rows=max_rows_display, show_all_columns=show_all_columns)
127196
else:
128-
console.print(_("[yellow]No HEASARC missions found.[/yellow]"))
197+
console.print(_("[yellow]No HEASARC missions found matching your criteria.[/yellow]"))
129198
except Exception as e:
130199
handle_astroquery_exception(ctx, e, _("HEASARC list missions"))
131200
raise typer.Exit(code=1)
132-
133201
return app

astroquery_cli/modules/nist_cli.py

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def get_app():
2323
_ = builtins._
2424
app = typer.Typer(
2525
name="nist",
26-
help=builtins._("Query the NIST Atomic Spectra Database."),
26+
help="Query the NIST Atomic Spectra Database.",
2727
invoke_without_command=True,
2828
no_args_is_help=False
2929
)
@@ -34,54 +34,46 @@ def nist_callback(
3434
ctx: typer.Context,
3535
query_string: Optional[str] = typer.Argument(
3636
None,
37-
help=builtins._(
38-
"Primary query input. Can be:\n"
37+
help="Primary query input. Can be:\n"
3938
" 1. A wavelength range (e.g., '2000 3000').\n"
4039
" 2. A line name (e.g., 'Fe II', 'H I').\n"
4140
"If a line name is provided without explicit --minwav/--maxwav, a broad default range will be used."
42-
),
4341
),
4442
minwav: Optional[float] = typer.Option(
4543
None,
46-
help=builtins._(
47-
"Explicit minimum wavelength (e.g., 2000). Overrides any wavelength range parsed from 'query_string'. "
44+
help="Explicit minimum wavelength (e.g., 2000). Overrides any wavelength range parsed from 'query_string'. "
4845
"Can be combined with '--linename'."
49-
),
5046
),
5147
maxwav: Optional[float] = typer.Option(
5248
None,
53-
help=builtins._(
54-
"Explicit maximum wavelength (e.g., 3000). Overrides any wavelength range parsed from 'query_string'. "
49+
help="Explicit maximum wavelength (e.g., 3000). Overrides any wavelength range parsed from 'query_string'. "
5550
"Can be combined with '--linename'."
56-
),
5751
),
5852
linename: Optional[str] = typer.Option(
5953
None,
60-
help=builtins._(
61-
"Explicit line name (e.g., 'Fe II', 'H I'). Overrides any line name parsed from 'query_string'. "
54+
help="Explicit line name (e.g., 'Fe II', 'H I'). Overrides any line name parsed from 'query_string'. "
6255
"Can be combined with explicit '--minwav' and '--maxwav' for a specific range."
63-
),
6456
),
6557
output_file: Optional[str] = common_output_options["output_file"],
6658
output_format: Optional[str] = common_output_options["output_format"],
6759
max_rows_display: int = typer.Option(
68-
25, help=builtins._("Maximum number of rows to display. Use -1 for all rows.")
60+
25, help="Maximum number of rows to display. Use -1 for all rows."
6961
),
7062
show_all_columns: bool = typer.Option(
71-
False, "--show-all-cols", help=builtins._("Show all columns in the output table.")
63+
False, "--show-all-cols", help="Show all columns in the output table."
7264
),
73-
test: bool = typer.Option(False, "--test", "-t", help=_("Enable test mode and print elapsed time.")),
65+
test: bool = typer.Option(False, "--test", "-t", help="Enable test mode and print elapsed time."),
7466
debug_flag: bool = typer.Option( # Renamed to avoid conflict with imported debug
7567
False,
7668
"--debug", # Removed -t to avoid conflict with --test
77-
help=_("Enable debug mode with verbose output."),
69+
help="Enable debug mode with verbose output.",
7870
envvar="AQC_DEBUG"
7971
),
8072
verbose: bool = typer.Option(
8173
False,
8274
"-v",
8375
"--verbose",
84-
help=_("Enable verbose output.")
76+
help="Enable verbose output."
8577
)
8678
):
8779
setup_debug_context(ctx, debug_flag, verbose)

0 commit comments

Comments
 (0)