2929 ScienceFilePath ,
3030 generate_imap_file_path ,
3131)
32- from imap_data_access .io import query
32+ from imap_data_access .io import query , spice_query
3333from imap_data_access .webpoda import download_daily_data
3434
3535
@@ -45,7 +45,7 @@ def _download_parser(args: argparse.Namespace):
4545 print (f"Successfully downloaded the file to: { output_path } " )
4646
4747
48- # ruff: noqa: PLR0912
48+ # ruff: noqa: PLR0912, PLR0915
4949def _print_query_results_table (query_results : list [dict ]):
5050 """Print the query results in a table.
5151
@@ -62,7 +62,9 @@ def _print_query_results_table(query_results: list[dict]):
6262
6363 # Get the database table
6464 query_table = ""
65- if "end_date" in query_results [0 ]:
65+ if "kernel_type" in query_results [0 ]:
66+ query_table = "spice"
67+ elif "end_date" in query_results [0 ]:
6668 query_table = "ancillary"
6769 elif "repointing" in query_results [0 ]:
6870 query_table = "science"
@@ -86,6 +88,14 @@ def _print_query_results_table(query_results: list[dict]):
8688 "Version" ,
8789 "Filename" ,
8890 ]
91+ spice_header_keys = {
92+ "Kernel Type" : "kernel_type" ,
93+ "Min Date" : "min_date_datetime" ,
94+ "Max Date" : "max_date_datetime" ,
95+ "Ingestion Date" : "ingestion_date" ,
96+ "Version" : "version" ,
97+ }
98+ headers_spice = [* spice_header_keys .keys (), "Filename" ]
8999 # Boolean to check if CR is present in any science files
90100 cr_flag = query_table == "science" and any (
91101 item .get ("cr" ) not in (None , "" , []) for item in query_results
@@ -104,16 +114,22 @@ def _print_query_results_table(query_results: list[dict]):
104114 # Set appropriate headers for desired table
105115 if query_table == "science" :
106116 headers = headers_science
117+ elif query_table == "spice" :
118+ headers = headers_spice
107119 else :
108120 headers = headers_ancillary
109121
110122 # Calculate the maximum width for each column based on the header and the data
111123 # have to adjust Ingestion Date, Filename, and CR to properly align
112124 column_widths = {}
113125 for header in headers [:- 1 ]:
126+ if query_table == "spice" :
127+ data_key = spice_header_keys [header ]
128+ else :
129+ data_key = header .lower ()
114130 column_widths [header ] = max (
115131 len (header ),
116- * (len (str (item .get (header . lower () , "" ))) for item in query_results ),
132+ * (len (str (item .get (data_key , "" ))) for item in query_results ),
117133 )
118134
119135 column_widths ["Ingestion Date" ] = max (
@@ -128,12 +144,10 @@ def _print_query_results_table(query_results: list[dict]):
128144 len ("CR" ), * (len (str (item .get ("cr" , "" ))) for item in query_results )
129145 )
130146
147+ file_key = "file_name" if query_table == "spice" else "file_path"
131148 column_widths ["Filename" ] = max (
132149 len ("Filename" ),
133- * (
134- len (os .path .basename (item .get ("file_path" , "" )))
135- for item in query_results
136- ),
150+ * (len (os .path .basename (item .get (file_key , "" ))) for item in query_results ),
137151 )
138152
139153 # Create the format string dynamically based on the number of columns
@@ -153,7 +167,11 @@ def _print_query_results_table(query_results: list[dict]):
153167
154168 # Print data
155169 for item in query_results :
156- if query_table == "ancillary" :
170+ if query_table == "spice" :
171+ values = [
172+ str (item .get (spice_header_keys [header ], "" )) for header in headers [:- 1 ]
173+ ] + [str (item .get ("file_name" , "" ))]
174+ elif query_table == "ancillary" :
157175 values = [
158176 str (item .get ("instrument" , "" )),
159177 str (item .get ("descriptor" , "" )),
@@ -210,6 +228,7 @@ def _query_parser(args: argparse.Namespace):
210228 "version" ,
211229 "extension" ,
212230 "filename" ,
231+ "type" ,
213232 ]
214233
215234 # Filter to get the arguments of interest from the namespace
@@ -262,9 +281,21 @@ def _query_parser(args: argparse.Namespace):
262281
263282 # SPICE query table
264283 elif args .table == "spice" :
265- raise NotImplementedError ("SPICE query not implemented yet." )
284+ spice_valid_args = [
285+ "start_date" ,
286+ "end_date" ,
287+ "ingestion_start_date" ,
288+ "ingestion_end_date" ,
289+ "type" ,
290+ "version" ,
291+ ]
292+ query_params = {
293+ key : value for key , value in query_params .items () if key in spice_valid_args
294+ }
295+ query_results = spice_query (** query_params )
266296
267- query_results = query (** query_params )
297+ else :
298+ query_results = query (** query_params )
268299
269300 if args .output_format == "table" :
270301 _print_query_results_table (query_results )
@@ -401,6 +432,18 @@ def add_query_args(subparser: ArgumentParser) -> None:
401432 "processing.readthedocs.io/en/latest/development-guide/style-guide/naming-conventions"
402433 ".html#data-product-file-naming-conventions" ,
403434 )
435+ subparser .add_argument (
436+ "--type" ,
437+ type = str ,
438+ required = False ,
439+ help = "SPICE kernel type. Only used with --table spice. "
440+ "Valid types: attitude_history, attitude_predict, spin, repoint, "
441+ "ephemeris_reconstructed, ephemeris_nominal, ephemeris_predicted, "
442+ "ephemeris_90days, ephemeris_long, ephemeris_launch, planetary_ephemeris, "
443+ "planetary_constants, leapseconds, pointing_attitude, spacecraft_clock, "
444+ "imap_frames, science_frames, metakernel, thruster, lagrange_point, "
445+ "earth_attitude." ,
446+ )
404447 subparser .set_defaults (func = _query_parser )
405448
406449
@@ -430,7 +473,7 @@ def _reprocess_parser(args: argparse.Namespace):
430473
431474
432475# PLR0915: too many statements
433- def main (): # noqa: PLR0915
476+ def main ():
434477 """Parse the command line arguments.
435478
436479 Run the command line interface to the IMAP Data Access API.
0 commit comments