Debugging DRP Outputs
This page describes several techniques to find problems and inconsistencies from DRP Processing.
The first step is to load a copy of the time series database.
[1]:
from modules.quicklook.src.analyze_time_series import AnalyzeTimeSeries
from datetime import datetime
import pandas as pd
pd.set_option('display.max_rows', None) # show all rows
pd.set_option('display.max_columns', None) # show all columns without wrapping
pd.set_option('display.width', 200)
db_path = '/data/time_series/kpf_ts.db'
myTS = AnalyzeTimeSeries(db_path=db_path)
INFO: Starting AnalyzeTimeSeries
INFO: Jupyter Notebook environment detected.
INFO: Path of database file: /data/time_series/kpf_ts.db
INFO: Base data directory: /data/L0
INFO: Primary table 'kpfdb' created/updated successfully.
INFO: Metadata table 'kpfdb_metadata' created/updated successfully.
INFO: Summary: 381519 obs x 1669 cols over 830 days in 20221202-20250427; updated 2025-04-27 18:03:29
Finding Observations with inconsistent DRPTAG values between 2D, L1, and L2 data
The code below returns a dataframe with the DRPTAG values for each data product.
[2]:
start_date = datetime(2024, 1, 1)
end_date = datetime(2024, 12, 31)
columns_to_display = ['ObsID', 'OBJECT', 'Source', 'DRPTAG2D', 'DRPTAGL1', 'DRPTAGL2', 'DATAPRL0', 'KWRDPRL0', 'TIMCHKL0', 'GOODREAD', 'DATAPR2D',]
df = myTS.dataframe_from_db(columns_to_display, start_date=start_date, end_date=end_date, not_junk=True)
Now let’s filter this table for cases where DRPTAG values are not equal and print the results. The selection criterion removes observations that failed one of five Quality Control tests. The results are printed in a table with links to Jump, a web-based portal used by the KPF Science Team. The method print_df_with_obsid_links() can use another URL base with the argument url_stub.
[3]:
condition = (
(df['DATAPRL0'] != 0) &
(df['KWRDPRL0'] != 0) &
(df['TIMCHKL0'] != 0) &
(df['GOODREAD'] != 0) &
(df['DATAPR2D'] != 0) &
(
(df['DRPTAG2D'] != df['DRPTAGL1']) |
((df['DRPTAGL2'].notna()) & (df['DRPTAG2D'] != df['DRPTAGL2']))
)
)
filtered_df = df.loc[condition, columns_to_display]
nrows=20
print(f'Number of observations: {len(filtered_df)}')
print()
print(f'First {nrows} rows:')
myTS.print_df_with_obsid_links(filtered_df.sort_values('ObsID'), nrows=nrows)
Number of observations: 323
First 20 rows:
| ObsID | OBJECT | Source | DRPTAG2D | DRPTAGL1 | DRPTAGL2 | DATAPRL0 | KWRDPRL0 | TIMCHKL0 | GOODREAD | DATAPR2D |
|---|---|---|---|---|---|---|---|---|---|---|
| KP.20240101.09954.24 | autocal-une-sci-eve | UNe | v2.9.1 | v2.9.1 | v2.8.2 | 1 | 1 | 1 | 1.0 | 1 |
| KP.20240101.10321.42 | autocal-une-sky-eve | UNe | v2.9.1 | v2.9.1 | v2.8.2 | 1 | 1 | 1 | 1.0 | 1 |
| KP.20240101.24652.60 | T006324 | Star | v2.9.1 | v2.8.2 | v2.8.2 | 1 | 1 | 1 | 1.0 | 1 |
| KP.20240104.33636.71 | autocal-etalon-all-night | Etalon | v2.9.1 | v2.9.1 | v2.8.2 | 1 | 1 | 1 | 1.0 | 1 |
| KP.20240107.76145.23 | SoCal | Sun | v2.9.1 | v2.9.1 | v2.8.2 | 1 | 1 | 1 | 1.0 | 1 |
| KP.20240108.00341.09 | autocal-flat-all | Flat | v2.9.1 | v2.9.1 | v2.8.2 | 1 | 1 | 1 | 1.0 | 1 |
| KP.20240108.10901.78 | autocal-une-all-eve | UNe | v2.9.1 | v2.9.1 | v2.8.2 | 1 | 1 | 1 | 1.0 | 1 |
| KP.20240109.11203.51 | autocal-lfc-all-eve | LFC | v2.9.1 | v2.9.1 | v2.8.2 | 1 | 1 | 1 | 1.0 | 1 |
| KP.20240109.80999.38 | autocal-flat-all | Flat | v2.9.1 | v2.9.1 | v2.8.2 | 1 | 1 | 1 | 1.0 | 1 |
| KP.20240111.66044.02 | autocal-etalon-all-morn | Etalon | v2.9.1 | v2.9.1 | v2.8.2 | 1 | 1 | 1 | 1.0 | 1 |
| KP.20240117.40788.71 | autocal-etalon-all-night | Etalon | v2.9.1 | v2.9.1 | v2.8.2 | 1 | 1 | 1 | 1.0 | 1 |
| KP.20240121.40026.09 | autocal-etalon-all-night | Etalon | v2.9.1 | v2.9.1 | v2.8.2 | 1 | 1 | 1 | 1.0 | 1 |
| KP.20240123.09376.92 | autocal-etalon-all-eve | Etalon | v2.9.1 | v2.9.1 | v2.8.2 | 1 | 1 | 1 | 1.0 | 1 |
| KP.20240123.09954.72 | autocal-une-sci-eve | UNe | v2.9.1 | v2.9.1 | v2.8.2 | 1 | 1 | 1 | 1.0 | 1 |
| KP.20240123.36702.72 | T001694 | Star | v2.9.1 | v2.8.2 | v2.8.2 | 1 | 1 | 1 | 1.0 | 1 |
| KP.20240124.10065.69 | autocal-une-sci-eve | UNe | v2.9.1 | v2.9.1 | v2.8.2 | 1 | 1 | 1 | 1.0 | 1 |
| KP.20240127.09793.39 | autocal-une-sci-eve | UNe | v2.9.1 | v2.9.1 | v2.8.2 | 1 | 1 | 1 | 1.0 | 1 |
| KP.20240127.24589.92 | autocal-etalon-all-night | Etalon | v2.9.1 | v2.8.2 | v2.8.2 | 1 | 1 | 1 | 1.0 | 1 |
| KP.20240208.06105.83 | LFC-service-mission | LFC | v2.9.1 | v2.9.1 | v2.8.2 | 1 | 1 | 1 | 1.0 | 1 |
| KP.20240208.14251.93 | LFC-service-mission | LFC | v2.9.1 | v2.9.1 | v2.8.2 | 1 | 1 | 1 | 1.0 | 1 |
To help diagnose the problems, we can make a table of the combinations of DRPTAG by data level.
[4]:
# Group by the three columns and count how many rows for each combination
summary = filtered_df.groupby(['DRPTAG2D', 'DRPTAGL1', 'DRPTAGL2']).size().reset_index(name='Count')
# Format and print a text table
print(f"{'DRPTAG2D':<15} {'DRPTAGL1':<15} {'DRPTAGL2':<15} {'Count':<5}")
print("-" * 55)
for _, row in summary.iterrows():
print(f"{row['DRPTAG2D']:<15} {row['DRPTAGL1']:<15} {row['DRPTAGL2']:<15} {row['Count']:<5}")
DRPTAG2D DRPTAGL1 DRPTAGL2 Count
-------------------------------------------------------
v2.9.0 v2.8.2 v2.8.2 1
v2.9.0 v2.9.0 v2.8.2 27
v2.9.1 v2.8.2 v2.8.2 3
v2.9.1 v2.9.1 v2.7.3 6
v2.9.1 v2.9.1 v2.8.2 285
Printing Errors from Log Files
The method print_log_error_report() searches the log files (assumed to be in /data/logs/, but configurable with the argument ‘log_dir’) and prints log lines with ‘[ERROR]’. Only the first five obsevations in the dataframe are processed below.
[5]:
myTS.print_log_error_report(filtered_df.head(5))
ObsID: KP.20240101.09954.24
Log file: /data/logs/20240101/KP.20240101.09954.24.log
Log modification date: 2025-04-26 05:38:17 UTC
Errors in log file:
[KP.20240101.09954.24.log][ERROR]:Problem with determining age of WLSFILE: "Keyword 'WLSFILE' not found."
[KP.20240101.09954.24.log][ERROR]:Problem with determining age of WLSFILE2: "Keyword 'WLSFILE2' not found."
[KP.20240101.09954.24.log][ERROR]:Failed executing primitive RadialVelocity: Objective function has encountered a non-finite value, this will cause the fit to fail!
--------------------------------------------------
ObsID: KP.20240101.10321.42
Log file: /data/logs/20240101/KP.20240101.10321.42.log
Log modification date: 2025-04-26 05:38:06 UTC
Errors in log file:
[KP.20240101.10321.42.log][ERROR]:Problem with determining age of WLSFILE: "Keyword 'WLSFILE' not found."
[KP.20240101.10321.42.log][ERROR]:Problem with determining age of WLSFILE2: "Keyword 'WLSFILE2' not found."
[KP.20240101.10321.42.log][ERROR]:Failed executing primitive RadialVelocity: Objective function has encountered a non-finite value, this will cause the fit to fail!
--------------------------------------------------
ObsID: KP.20240101.24652.60
Log file: /data/logs/20240101/KP.20240101.24652.60.log
Log modification date: 2025-04-26 05:22:44 UTC
Errors in log file:
No [ERROR] lines found.
--------------------------------------------------
ObsID: KP.20240104.33636.71
Log file: /data/logs/20240104/KP.20240104.33636.71.log
Log modification date: 2025-04-26 01:26:53 UTC
Errors in log file:
[KP.20240104.33636.71.log][ERROR]:Problem with determining age of WLSFILE: "Keyword 'WLSFILE' not found."
[KP.20240104.33636.71.log][ERROR]:Problem with determining age of WLSFILE2: "Keyword 'WLSFILE2' not found."
[KP.20240104.33636.71.log][ERROR]:Failed executing primitive BaryCorrTable: operands could not be broadcast together with shapes (56,) (55,)
--------------------------------------------------
ObsID: KP.20240107.76145.23
Log file: /data/logs/20240107/KP.20240107.76145.23.log
Log modification date: 2025-04-25 19:28:07 UTC
Errors in log file:
[KP.20240107.76145.23.log][ERROR]:Problem with determining age of WLSFILE: "Keyword 'WLSFILE' not found."
[KP.20240107.76145.23.log][ERROR]:Problem with determining age of WLSFILE2: "Keyword 'WLSFILE2' not found."
[KP.20240107.76145.23.log][ERROR]:Failed executing primitive RadialVelocity: Objective function has encountered a non-finite value, this will cause the fit to fail!
--------------------------------------------------
Aggregated Error Reports
The method print_log_error_report() can also make an aggregated report that lists the frequency of different error messages in the log files.
[6]:
myTS.print_log_error_report(filtered_df, aggregated_summary=True)
Aggregated Error Summary:
| Count | Error Message |
|---|---|
| 318 | Problem with determining age of WLSFILE: "Keyword 'WLSFILE' not found." |
| 318 | Problem with determining age of WLSFILE2: "Keyword 'WLSFILE2' not found." |
| 309 | Failed executing primitive RadialVelocity: Objective function has encountered a non-finite value, this will cause the fit to fail! |
| 5 | Failed executing primitive BaryCorrTable: operands could not be broadcast together with shapes (56,) (55,) |
| 2 | Failed executing primitive BaryCorrTable: operands could not be broadcast together with shapes (22,) (21,) |
| 2 | Failed executing primitive BaryCorrTable: operands could not be broadcast together with shapes (32,) (31,) |
| 1 | Failed executing primitive SpectralExtraction: Not enough free space to write 133171200 bytes |