Creates a Siril job file for a target by scanning the data folder structure, reading FITS headers for temperature, and finding matching calibration files.
Given a target name (e.g., M45), create a job JSON file by scanning the data folders.
Read settings.json in the project root to get base_path.
List date folders for the target:
ls "{base_path}/{target}"
For each date folder, list filter/exposure subfolders:
ls "{base_path}/{target}/{date}"
Filter folders are named {filter}{exposure} (e.g., L180, R300, Ha180, S180).
Read the sensor temperature from a FITS file header. Pick any .fit or .fits file from a light folder:
ls "{base_path}/{target}/{date}/{filter_folder}"
Then read the temperature:
uv run python -c "from astropy.io import fits; h=fits.getheader(r'{path_to_fit_file}'); print(h.get('CCD-TEMP') or h.get('SET-TEMP'))"
Round to nearest integer (e.g., -9.8 -> -10).
List available calibration dates:
ls "{base_path}/calibration/raw/biases"
ls "{base_path}/calibration/raw/darks"
ls "{base_path}/calibration/raw/flats"
Dark folders include temperature in the name: {YYYY_MM_DD}_{temp}C (e.g., 2025_01_23_-10C).
Calibration matching:
If no darks exist at the target temperature, use the closest available and set dark_temp_override in options. Otherwise, do not set dark_temp_override.
Based on filters found:
LRGBRGBSHOHOOFormat: {target}_{season}{year}
Determine season from the most recent light date:
Use the year of the most recent session.
Write to jobs/{target}.json.
{
"name": "{target}_{season}{year}",
"type": "LRGB",
"calibration": {
"bias": "2024_08_05",
"darks": "2025_01_23",
"flats": "2025_01_19"
},
"lights": {
"L": [
"{target}/{date1}/L180",
"{target}/{date2}/L180"
],
"R": [
"{target}/{date1}/R180",
"{target}/{date2}/R180"
],
"G": [
"{target}/{date1}/G180",
"{target}/{date2}/G180"
],
"B": [
"{target}/{date1}/B180",
"{target}/{date2}/B180"
]
},
"output": "{target}/processed",
"options": {}
}
LRGB job (M31):
LRGBNarrowband job (IC443):
SHO"palette": "SHO"LRGB + Ha:
LRGBHa key in lights alongside L, R, G, BRun the job:
uv run python run_job.py jobs/{target}.json
Other run options:
uv run python run_job.py jobs/{target}.json --validate # Validate only
uv run python run_job.py jobs/{target}.json --dry-run # Dry run
uv run python run_job.py jobs/{target}.json --stage preprocess # Run specific stage
Monitor the log file in logs/{target}_{timestamp}.log for:
After the job completes, review the log output and report any issues to the user.