Skip to content

Instantly share code, notes, and snippets.

@TheCyberBrick
Last active August 26, 2023 17:00
Show Gist options
  • Save TheCyberBrick/ce4f3920c0497802d7bcfb3d0b190229 to your computer and use it in GitHub Desktop.
Save TheCyberBrick/ce4f3920c0497802d7bcfb3d0b190229 to your computer and use it in GitHub Desktop.
Evaluation Job
{
"grouping_filters": [
{
"grouping_key": "Keyword:RTTARG",
"pattern": ".+"
}
],
"exporters": [
{
"id": "voyager",
"config": {
"application_server_hostname": "c8.plleagle.com",
"application_server_port": 5950,
"credentials_file": "%userprofile%/voyager_credentials.json",
"min_rating_threshold": 5,
"reset_ratings_and_restore": false
}
}
],
"evaluation_formula": [
"# Weights",
"BaseWeight := 40;",
"FWHMWeight := 0;",
"FWHMxWeight := 40;",
"FWHMyWeight := 10;",
"EccentricityWeight := 20;",
"MedianWeight := 10;",
"",
"# Calculate FWHMx and FWHMy, i.e. the major and minor axes of the PSF fits",
"FWHMx := FWHM / MAX(1 - Eccentricity^2, 0.0001)^0.25;",
"FWHMy := FWHM * MAX(1 - Eccentricity^2, 0.0001)^0.25;",
"",
"# Calculate normalized FWHM, FWHMx, FWHMy, Eccentricity & Median",
"FWHMRange := FWHMMax - FWHMMin;",
"FWHMNormalized := IF(FWHMRange < 0.0001, 0.5, (FWHM - FWHMMin) / FWHMRange);",
"FWHMxRange := FWHMxMax - FWHMxMin;",
"FWHMxNormalized := IF(FWHMxRange < 0.0001, 0.5, (FWHMx - FWHMxMin) / FWHMxRange);",
"FWHMyRange := FWHMyMax - FWHMyMin;",
"FWHMyNormalized := IF(FWHMyRange < 0.0001, 0.5, (FWHMy - FWHMyMin) / FWHMyRange);",
"EccentricityRange := EccentricityMax - EccentricityMin;",
"EccentricityNormalized := IF(EccentricityRange < 0.0001, 0.5, (Eccentricity - EccentricityMin) / EccentricityRange);",
"MedianRange := MedianMax - MedianMin;",
"MedianNormalized := IF(MedianRange < 1, 0.5, (Median - MedianMin) / MedianRange);",
"",
"# Calculate rating",
"Rating := BaseWeight",
"+ FWHMWeight * (1 - FWHMNormalized)",
"+ FWHMxWeight * (1 - FWHMxNormalized)",
"+ FWHMyWeight * (1 - FWHMyNormalized)",
"+ EccentricityWeight * (1 - EccentricityNormalized)",
"+ MedianWeight * (1 - MedianNormalized);",
"",
"RatingRange := RatingMax - RatingMin;",
"RatingNormalized := IF(RatingRange < 0.0001, 0.5, (Rating - RatingMin) / RatingRange);",
"",
"# Return normalized rating between 1 and 10",
"RatingNormalized * 9",
""
],
"parallel_tasks": 16,
"parallel_io": 2,
"grouping_keys": [
"Object",
"Filter"
],
"grouping_keys_required": false,
"output_logs_path": "logs",
"cache_path": "cache",
"max_image_size": 805306368,
"max_image_width": 8192,
"max_image_height": 8192
}
@TheCyberBrick
Copy link
Author

TheCyberBrick commented Jul 2, 2023

This job file evaluates all files on the specified path and then sends the ratings (1 - 10) determined by the evaluation formula to Voyager RoboTarget. If a rating is below 5 then the corresponding shot is (reversibly) marked as deleted in RoboTarget (the FITS file is not deleted). If a rating climbs back to 5 or above then the shot is restored. The shot corresponding to the evaluated FITS file is determined by the RTTARG/RTSHOT FITS headers added by Voyager (this was implemented a few Voyager updates ago). If this FITS keyword is not present, then the file is skipped (see "grouping_filters").
The images are evaluated in groups, determined by the object name and filter in the FITS header. Like this, only images that are similar in nature are compared with each other. For example: comparing a luminance subframe to an H-alpha subframe does not make much sense. It might also make sense to group by telescope (could be done via FITS header grouping keyword), in case multiple telescopes are used for the same target.
Most of the results are cached in the "cache" folder next to the job file. The next run will be much quicker because only new images will have to be re-analyzed. This allows it to easily scale to thousands of images.
Command to run the job file:

FitsRatingToolCli.exe --job "voyagerjob.json" --progress --path "C:\path\to\fits\files" --filepattern "^.*(?:\\|\/)(?![Cc][Aa][Ll][Ii][Bb][Rr][Aa][Tt][Ee][Dd])[^\\\/]*(?<![Cc][Aa][Ll][Ii][Bb][Rr][Aa][Tt][Ee][Dd])(?:\\|\/)[^\\\/]*$"

The specified filepattern regex is optional. In my case I use it to exclude exclude images in subdirectories which contain the word "calibrated".

@TheCyberBrick
Copy link
Author

TheCyberBrick commented Jul 2, 2023

Used evaluation formula:

# Weights
BaseWeight := 40;
FWHMWeight := 0;
FWHMxWeight := 40;
FWHMyWeight := 10;
EccentricityWeight := 10;
MedianWeight := 10;

# Calculate FWHMx and FWHMy, i.e. the major and minor axes of the PSF fits
FWHMx := FWHM / MAX(1 - Eccentricity^2, 0.0001)^0.25;
FWHMy := FWHM * MAX(1 - Eccentricity^2, 0.0001)^0.25;

# Calculate normalized FWHM, FWHMx, FWHMy, Eccentricity & Median
FWHMRange := FWHMMax - FWHMMin;
FWHMNormalized := IF(FWHMRange < 0.0001, 0.5,  (FWHM - FWHMMin) / FWHMRange);
FWHMxRange := FWHMxMax - FWHMxMin;
FWHMxNormalized := IF(FWHMxRange < 0.0001, 0.5,  (FWHMx - FWHMxMin) / FWHMxRange);
FWHMyRange := FWHMyMax - FWHMyMin;
FWHMyNormalized := IF(FWHMyRange < 0.0001, 0.5,  (FWHMy - FWHMyMin) / FWHMyRange);
EccentricityRange := EccentricityMax - EccentricityMin;
EccentricityNormalized := IF(EccentricityRange < 0.0001, 0.5, (Eccentricity - EccentricityMin) / EccentricityRange);
MedianRange := MedianMax - MedianMin;
MedianNormalized := IF(MedianRange < 1, 0.5, (Median - MedianMin) / MedianRange);

# Calculate rating
Rating := BaseWeight
+ FWHMWeight * (1 - FWHMNormalized)
+ FWHMxWeight * (1 - FWHMxNormalized)
+ FWHMyWeight * (1 - FWHMyNormalized)
+ EccentricityWeight * (1 - EccentricityNormalized)
+ MedianWeight * (1 - MedianNormalized);

RatingRange := RatingMax - RatingMin;
RatingNormalized := IF(RatingRange < 0.0001, 0.5,  (Rating - RatingMin) / RatingRange);

# Return normalized rating between 1 and 10
RatingNormalized * 9

@rixonreed
Copy link

Hi, I’m digging into this. Thank you for your help so far. How can I run this evaluator at the end of the night’s imaging using dragscript?

Or even better, can it automatically run each time a sub is taken? How could that happen?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment