Ejemplo n.º 1
0
        public async Task <PlateSolveResult> SolveAsync(IImageData source, PlateSolveParameter parameter, IProgress <ApplicationStatus> progress, CancellationToken canceltoken)
        {
            EnsureSolverValid(parameter);
            var imageProperties = PlateSolveImageProperties.Create(parameter, source);

            return(await SolveAsyncImpl(source, parameter, imageProperties, progress, canceltoken));
        }
Ejemplo n.º 2
0
        protected override async Task <PlateSolveResult> SolveAsyncImpl(
            IImageData source,
            PlateSolveParameter parameter,
            PlateSolveImageProperties imageProperties,
            IProgress <ApplicationStatus> progress,
            CancellationToken cancelToken)
        {
            PlateSolveResult result = new PlateSolveResult();

            try {
                progress.Report(new ApplicationStatus()
                {
                    Status = "Authenticating to Astrometery.net..."
                });
                var session = await GetAuthenticationToken(cancelToken);

                progress.Report(new ApplicationStatus()
                {
                    Status = "Uploading image to Astrometry.net..."
                });
                var jobId = await SubmitImageJob(progress, source, session, cancelToken);

                progress.Report(new ApplicationStatus()
                {
                    Status = $"Getting result for Astrometry.net job {jobId}..."
                });
                JobResult jobinfo = await GetJobResult(jobId, cancelToken);

                result.Orientation = jobinfo.calibration.orientation;
                /* The orientation is mirrored on the x-axis */
                result.Flipped     = jobinfo.calibration.parity < 0;
                result.Orientation = 180 - result.Orientation + 360;

                result.Pixscale    = jobinfo.calibration.pixscale;
                result.Coordinates = new Utility.Astrometry.Coordinates(jobinfo.calibration.ra, jobinfo.calibration.dec, Utility.Astrometry.Epoch.J2000, Utility.Astrometry.Coordinates.RAType.Degrees);
                result.Radius      = jobinfo.calibration.radius;
            } catch (OperationCanceledException) {
                result.Success = false;
            } catch (Exception ex) {
                result.Success = false;
                Notification.ShowError($"Error plate solving with Astrometry.net. {ex.Message}");
            }

            if (result.Success)
            {
                progress.Report(new ApplicationStatus()
                {
                    Status = "Solved"
                });
            }
            else
            {
                progress.Report(new ApplicationStatus()
                {
                    Status = "Solve failed"
                });
            }
            return(result);
        }
Ejemplo n.º 3
0
        protected override void EnsureSolverValid(PlateSolveParameter parameter)
        {
            if (string.IsNullOrWhiteSpace(_apikey))
            {
                throw new ArgumentException("Astrometry.net API key is not configured");
            }

            if (string.IsNullOrWhiteSpace(_apiurl))
            {
                throw new ArgumentException("Astrometry.net API URL is not configured");
            }

            // Trailing spaces on the API key text sometimes sneak in if it has been copy and pasted
            if (Regex.IsMatch(_apikey, @"\s"))
            {
                throw new ArgumentException("Astrometry.net API key contains an invalid space character");
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Gets start arguments for Platesolve2 out of RA,Dec, ArcDegWidth, ArcDegHeight and ImageFilePath
        /// </summary>
        /// <returns></returns>
        protected override string GetArguments(
            string imageFilePath,
            string outputFilePath,
            PlateSolveParameter parameter,
            PlateSolveImageProperties imageProperties)
        {
            var args = new string[] {
                Astrometry.ToRadians(parameter.Coordinates.RADegrees).ToString(CultureInfo.InvariantCulture),
                Astrometry.ToRadians(parameter.Coordinates.Dec).ToString(CultureInfo.InvariantCulture),
                Astrometry.ToRadians(imageProperties.FoVW).ToString(CultureInfo.InvariantCulture),
                Astrometry.ToRadians(imageProperties.FoVH).ToString(CultureInfo.InvariantCulture),
                parameter.Regions.ToString(),
                imageFilePath,
                "0"
            };

            return(string.Join(",", args));
        }
Ejemplo n.º 5
0
        protected override async Task <PlateSolveResult> SolveAsyncImpl(
            IImageData source,
            PlateSolveParameter parameter,
            PlateSolveImageProperties imageProperties,
            IProgress <ApplicationStatus> progress,
            CancellationToken cancelToken)
        {
            var result = new PlateSolveResult()
            {
                Success = false
            };
            string imagePath = null, outputPath = null;

            try {
                //Copy Image to local app data
                imagePath = await PrepareAndSaveImage(source, cancelToken);

                progress.Report(new ApplicationStatus()
                {
                    Status = Locale.Loc.Instance["LblSolving"]
                });

                outputPath = GetOutputPath(imagePath);

                await StartCLI(imagePath, outputPath, parameter, imageProperties, progress, cancelToken);

                //Extract solution coordinates
                result = ReadResult(outputPath, parameter, imageProperties);
            } finally {
                progress.Report(new ApplicationStatus()
                {
                    Status = string.Empty
                });
                if (imagePath != null && File.Exists(imagePath))
                {
                    File.Delete(imagePath);
                }
                if (outputPath != null && File.Exists(outputPath))
                {
                    File.Delete(outputPath);
                }
            }
            return(result);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Creates the arguments to launch ASTAP process
        /// </summary>
        /// <returns></returns>
        /// <remarks>http://www.hnsky.org/astap.htm#astap_command_line</remarks>
        protected override string GetArguments(
            string imageFilePath,
            string outputFilePath,
            PlateSolveParameter parameter,
            PlateSolveImageProperties imageProperties)
        {
            var args = new List <string>();

            //File location to solve
            args.Add($"-f \"{imageFilePath}\"");

            //Field height of image
            var fov = Math.Round(imageProperties.FoVH, 6);

            args.Add($"-fov {fov.ToString(CultureInfo.InvariantCulture)}");

            //Downsample factor
            args.Add($"-z {parameter.DownSampleFactor}");

            //Max number of stars
            args.Add($"-s {parameter.MaxObjects}");

            if (parameter.SearchRadius > 0 && parameter.Coordinates != null)
            {
                //Search field radius
                args.Add($"-r {parameter.SearchRadius}");

                var ra = Math.Round(parameter.Coordinates.RA, 6);
                //Right Ascension in degrees
                args.Add($"-ra {ra.ToString(CultureInfo.InvariantCulture)}");

                var spd = Math.Round(parameter.Coordinates.Dec + 90.0, 6);
                //South pole distance in degrees
                args.Add($"-spd {spd.ToString(CultureInfo.InvariantCulture)}");
            }
            else
            {
                //Search field radius
                args.Add($"-r {180}");
            }

            return(string.Join(" ", args));
        }
Ejemplo n.º 7
0
        protected override string GetArguments(
            string imageFilePath,
            string outputFilePath,
            PlateSolveParameter parameter,
            PlateSolveImageProperties imageProperties)
        {
            var args = new List <string>();

            var imageFilePathArg = imageFilePath.Replace("\\", "/");

            //FileName
            args.Add($"\"{imageFilePathArg}\"");

            //OutFile
            args.Add($"\"{outputFilePath}\"");

            //FocalLength
            args.Add(parameter.FocalLength.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture));

            //PixelSize
            args.Add(parameter.PixelSize.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture));

            if (parameter.Coordinates != null)
            {
                //CurrentRA
                args.Add(parameter.Coordinates.RADegrees.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture));

                //CurrentDec
                args.Add(parameter.Coordinates.Dec.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture));
            }
            else
            {
                args.Add("0");
                args.Add("0");
            }

            //NearRadius
            args.Add(parameter.SearchRadius.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture));

            return($"/solvefile {string.Join(" ", args)}");
        }
Ejemplo n.º 8
0
        protected override void EnsureSolverValid(PlateSolveParameter parameter)
        {
            if (string.IsNullOrWhiteSpace(this.executableLocation))
            {
                throw new ASTAPValidationFailedException($"ASTAP executable location missing! Please enter the location in the platesolver options!");
            }
            if (!File.Exists(this.executableLocation))
            {
                throw new ASTAPValidationFailedException($"ASTAP executable not found at {this.executableLocation}");
            }
            var astapVersionInfo = FileVersionInfo.GetVersionInfo(this.executableLocation);

            if (astapVersionInfo.FileVersion == null)
            {
                // Version below 0.9.1.0
                // Only allows downsample in the range of 1 to 4
                if (parameter.DownSampleFactor == 0)
                {
                    throw new ASTAPValidationFailedException($"ASTAP version below 0.9.1.0 does not allow auto downsample factor value of 0! Please update your ASTAP version!");
                }
            }
        }
Ejemplo n.º 9
0
        protected override PlateSolveResult ReadResult(
            string outputFilePath,
            PlateSolveParameter parameter,
            PlateSolveImageProperties imageProperties)
        {
            var result = new PlateSolveResult()
            {
                Success = false
            };

            if (File.Exists(outputFilePath))
            {
                string[] lines = File.ReadAllLines(outputFilePath, Encoding.UTF8);
                if (lines.Length > 0)
                {
                    if (lines[0] == "OK" && lines.Length >= 8)
                    {
                        var ra  = double.Parse(lines[1]);
                        var dec = double.Parse(lines[2]);

                        result.Coordinates = new Coordinates(ra, dec, Epoch.J2000, Coordinates.RAType.Degrees);

                        var fovW = lines[3];
                        var fovH = lines[4];

                        result.Pixscale    = double.Parse(lines[5]);
                        result.Orientation = double.Parse(lines[6]);
                        /* Due to the way N.I.N.A. writes FITS files, the orientation is mirrored on the x-axis */
                        result.Orientation = 180 - result.Orientation + 360;

                        var focalLength = lines[7];

                        result.Success = true;
                    }
                }
            }
            return(result);
        }
Ejemplo n.º 10
0
        protected async Task StartCLI(string imageFilePath, string outputFilePath, PlateSolveParameter parameter, PlateSolveImageProperties imageProperties, IProgress <ApplicationStatus> progress, CancellationToken ct)
        {
            if (executableLocation != "cmd.exe" && !File.Exists(executableLocation))
            {
                throw new FileNotFoundException("Executable not found", executableLocation);
            }

            System.Diagnostics.Process          process   = new System.Diagnostics.Process();
            System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();

            startInfo.WindowStyle            = System.Diagnostics.ProcessWindowStyle.Normal;
            startInfo.FileName               = executableLocation;
            startInfo.UseShellExecute        = false;
            startInfo.RedirectStandardOutput = true;
            startInfo.CreateNoWindow         = true;
            startInfo.Arguments              = GetArguments(imageFilePath, outputFilePath, parameter, imageProperties);
            process.StartInfo           = startInfo;
            process.EnableRaisingEvents = true;

            process.OutputDataReceived += (object sender, System.Diagnostics.DataReceivedEventArgs e) => {
                progress.Report(new ApplicationStatus()
                {
                    Status = e.Data
                });
            };

            process.ErrorDataReceived += (object sender, System.Diagnostics.DataReceivedEventArgs e) => {
                progress.Report(new ApplicationStatus()
                {
                    Status = e.Data
                });
            };
            Logger.Debug($"Starting process '{executableLocation}' with args '{startInfo.Arguments}'");
            process.Start();
            await process.WaitForExitAsync(ct);
        }
Ejemplo n.º 11
0
        protected override string GetArguments(
            string imageFilePath,
            string outputFilePath,
            PlateSolveParameter parameter,
            PlateSolveImageProperties imageProperties)
        {
            List <string> options = new List <string>();

            options.Add("--overwrite");
            options.Add("--index-xyls none");
            options.Add("--corr none");
            options.Add("--rdls none");
            options.Add("--match none");
            options.Add("--new-fits none");
            //options.Add("-C cancel--crpix");
            options.Add("-center");
            options.Add($"--objs {parameter.MaxObjects}");
            options.Add("--no-plots");
            options.Add("--resort");
            options.Add($"--downsample {parameter.DownSampleFactor}");
            var lowArcSecPerPix  = imageProperties.ArcSecPerPixel - 0.2;
            var highArcSecPerPix = imageProperties.ArcSecPerPixel + 0.2;

            options.Add("--scale-units arcsecperpix");
            options.Add(string.Format("-L {0}", lowArcSecPerPix.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)));
            options.Add(string.Format("-H {0}", highArcSecPerPix.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)));

            if (parameter.SearchRadius > 0 && parameter.Coordinates != null)
            {
                options.Add($"--ra {parameter.Coordinates.RADegrees.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)}");
                options.Add($"--dec {parameter.Coordinates.Dec.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)}");
                options.Add($"--radius {parameter.SearchRadius.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)}");
            }

            return(string.Format("/C \"\"{0}\" --login -c '/usr/bin/solve-field {1} \"{2}\"'\"", bashLocation, string.Join(" ", options), imageFilePath.Replace("\\", "/")));
        }
Ejemplo n.º 12
0
 protected abstract string GetArguments(
     string imageFilePath,
     string outputFilePath,
     PlateSolveParameter parameter,
     PlateSolveImageProperties imageProperties);
Ejemplo n.º 13
0
        /// <summary>
        /// Extract result out of generated .axy file. File consists of three rows
        /// 1. row: RA,Dec,Code
        /// 2. row: Scale,Orientation,?,?,Stars
        /// </summary>
        /// <returns>PlateSolveResult</returns>
        protected override PlateSolveResult ReadResult(
            string outputFilePath,
            PlateSolveParameter parameter,
            PlateSolveImageProperties imageProperties)
        {
            PlateSolveResult result = new PlateSolveResult()
            {
                Success = false
            };

            if (File.Exists(outputFilePath))
            {
                using (var s = new StreamReader(outputFilePath)) {
                    string line;
                    int    linenr = 0;
                    while ((line = s.ReadLine()) != null)
                    {
                        string[] resultArr = line.Split(',');
                        if (linenr == 0)
                        {
                            if (resultArr.Length > 2)
                            {
                                double ra, dec;
                                int    status;
                                if (resultArr.Length == 5)
                                {
                                    /* workaround for when decimal separator is comma instead of point.
                                     * won't work when result contains even numbers tho... */
                                    status = int.Parse(resultArr[4]);
                                    if (status != 1)
                                    {
                                        /* error */
                                        result.Success = false;
                                        break;
                                    }

                                    ra  = double.Parse(resultArr[0] + "." + resultArr[1], CultureInfo.InvariantCulture);
                                    dec = double.Parse(resultArr[2] + "." + resultArr[3], CultureInfo.InvariantCulture);
                                }
                                else
                                {
                                    status = int.Parse(resultArr[2]);
                                    if (status != 1)
                                    {
                                        /* error */
                                        result.Success = false;
                                        break;
                                    }

                                    ra  = double.Parse(resultArr[0], CultureInfo.InvariantCulture);
                                    dec = double.Parse(resultArr[1], CultureInfo.InvariantCulture);
                                }

                                /* success */
                                result.Success     = true;
                                result.Coordinates = new Coordinates(Astrometry.ToDegree(ra), Astrometry.ToDegree(dec), Epoch.J2000, Coordinates.RAType.Degrees);
                            }
                        }
                        if (linenr == 1)
                        {
                            if (resultArr.Length > 2)
                            {
                                if (resultArr.Length > 5)
                                {
                                    /* workaround for when decimal separator is comma instead of point.
                                     * won't work when result contains even numbers tho... */
                                    result.Pixscale    = double.Parse(resultArr[0] + "." + resultArr[1], CultureInfo.InvariantCulture);
                                    result.Orientation = double.Parse(resultArr[2] + "." + resultArr[3], CultureInfo.InvariantCulture);

                                    result.Flipped = !(double.Parse(resultArr[4] + "." + resultArr[5], CultureInfo.InvariantCulture) < 0);
                                    if (result.Flipped)
                                    {
                                        result.Orientation = result.Orientation - 180;
                                    }
                                }
                                else
                                {
                                    result.Pixscale    = double.Parse(resultArr[0], CultureInfo.InvariantCulture);
                                    result.Orientation = double.Parse(resultArr[1], CultureInfo.InvariantCulture);

                                    result.Flipped = !(double.Parse(resultArr[2], CultureInfo.InvariantCulture) < 0);
                                    if (result.Flipped)
                                    {
                                        result.Orientation = result.Orientation - 180;
                                    }
                                }
                            }
                        }
                        linenr++;
                    }
                }
            }
            return(result);
        }
Ejemplo n.º 14
0
 protected virtual void EnsureSolverValid(PlateSolveParameter parameter)
 {
 }
Ejemplo n.º 15
0
 protected abstract Task <PlateSolveResult> SolveAsyncImpl(
     IImageData source,
     PlateSolveParameter parameter,
     PlateSolveImageProperties imageProperties,
     IProgress <ApplicationStatus> progress,
     CancellationToken canceltoken);
Ejemplo n.º 16
0
 protected abstract PlateSolveResult ReadResult(
     string outputFilePath,
     PlateSolveParameter parameter,
     PlateSolveImageProperties imageProperties);
Ejemplo n.º 17
0
        protected override PlateSolveResult ReadResult(string outputFilePath, PlateSolveParameter parameter, PlateSolveImageProperties imageProperties)
        {
            var result = new PlateSolveResult()
            {
                Success = false
            };

            if (File.Exists(outputFilePath))
            {
                var startInfo = new System.Diagnostics.ProcessStartInfo();
                startInfo.WindowStyle            = System.Diagnostics.ProcessWindowStyle.Normal;
                startInfo.FileName               = "cmd.exe";
                startInfo.UseShellExecute        = false;
                startInfo.RedirectStandardOutput = true;
                startInfo.CreateNoWindow         = true;
                startInfo.Arguments              = string.Format("/C \"\"{0}\" --login -c 'wcsinfo \"{1}\"'\"", bashLocation, outputFilePath.Replace("\\", "/"));
                using (var process = new System.Diagnostics.Process()) {
                    process.StartInfo = startInfo;
                    process.Start();
                    Dictionary <string, string> wcsinfo = new Dictionary <string, string>();
                    while (!process.StandardOutput.EndOfStream)
                    {
                        var line = process.StandardOutput.ReadLine();
                        if (line != null)
                        {
                            var valuepair = line.Split(' ');
                            if (valuepair != null && valuepair.Length == 2)
                            {
                                wcsinfo[valuepair[0]] = valuepair[1];
                            }
                        }
                    }

                    if (wcsinfo.ContainsKey("crval0") &&
                        wcsinfo.ContainsKey("crval1") &&
                        wcsinfo.ContainsKey("crpix0") &&
                        wcsinfo.ContainsKey("crpix1") &&
                        wcsinfo.ContainsKey("cd11") &&
                        wcsinfo.ContainsKey("cd12") &&
                        wcsinfo.ContainsKey("cd21") &&
                        wcsinfo.ContainsKey("cd22"))
                    {
                        var crval1 = double.Parse(wcsinfo["crval0"]);
                        var crval2 = double.Parse(wcsinfo["crval1"]);
                        var crpix1 = double.Parse(wcsinfo["crpix0"]);
                        var crpix2 = double.Parse(wcsinfo["crpix1"]);
                        var cd11   = double.Parse(wcsinfo["cd11"]);
                        var cd12   = double.Parse(wcsinfo["cd12"]);
                        var cd21   = double.Parse(wcsinfo["cd21"]);
                        var cd22   = double.Parse(wcsinfo["cd22"]);

                        var wcs = new WorldCoordinateSystem(
                            crval1,
                            crval2,
                            crpix1,
                            crpix2,
                            cd11,
                            cd12,
                            cd21,
                            cd22
                            );

                        /* Due to the way N.I.N.A. writes FITS files, the orientation is mirrored on the x-axis */
                        result.Flipped = !wcs.Flipped;
                    }

                    double ra = 0, dec = 0;
                    if (wcsinfo.ContainsKey("ra_center"))
                    {
                        ra = double.Parse(wcsinfo["ra_center"], CultureInfo.InvariantCulture);
                    }
                    if (wcsinfo.ContainsKey("dec_center"))
                    {
                        dec = double.Parse(wcsinfo["dec_center"], CultureInfo.InvariantCulture);
                    }
                    if (wcsinfo.ContainsKey("orientation_center"))
                    {
                        result.Orientation = double.Parse(wcsinfo["orientation_center"], CultureInfo.InvariantCulture);
                        /* Due to the way N.I.N.A. writes FITS files, the orientation is mirrored on the x-axis */
                        result.Orientation = 180 - result.Orientation + 360;
                    }
                    if (wcsinfo.ContainsKey("pixscale"))
                    {
                        result.Pixscale = double.Parse(wcsinfo["pixscale"], CultureInfo.InvariantCulture);
                    }

                    result.Coordinates = new Coordinates(ra, dec, Epoch.J2000, Coordinates.RAType.Degrees);
                    result.Success     = true;
                }
            }
            return(result);
        }
Ejemplo n.º 18
0
        protected override PlateSolveResult ReadResult(
            string outputFilePath,
            PlateSolveParameter parameter,
            PlateSolveImageProperties imageProperties)
        {
            var result = new PlateSolveResult()
            {
                Success = false
            };

            if (!File.Exists(outputFilePath))
            {
                Notification.ShowError("ASTAP - Plate solve failed. No output file found.");
                return(result);
            }

            var dict = File.ReadLines(outputFilePath)
                       .Where(line => !string.IsNullOrWhiteSpace(line))
                       .Select(line => line.Split(new char[] { '=' }, 2, 0))
                       .ToDictionary(parts => parts[0], parts => parts[1]);

            dict.TryGetValue("WARNING", out var warning);

            if (!dict.ContainsKey("PLTSOLVD") || dict["PLTSOLVD"] != "T")
            {
                dict.TryGetValue("ERROR", out var error);
                Notification.ShowError($"ASTAP - Plate solve failed.{Environment.NewLine}{warning}{Environment.NewLine}{error}");
                return(result);
            }

            if (!string.IsNullOrWhiteSpace(warning))
            {
                Notification.ShowWarning($"ASTAP - {warning}");
            }

            var wcs = new WorldCoordinateSystem(
                double.Parse(dict["CRVAL1"], CultureInfo.InvariantCulture),
                double.Parse(dict["CRVAL2"], CultureInfo.InvariantCulture),
                double.Parse(dict["CRPIX1"], CultureInfo.InvariantCulture),
                double.Parse(dict["CRPIX2"], CultureInfo.InvariantCulture),
                double.Parse(dict["CD1_1"], CultureInfo.InvariantCulture),
                double.Parse(dict["CD1_2"], CultureInfo.InvariantCulture),
                double.Parse(dict["CD2_1"], CultureInfo.InvariantCulture),
                double.Parse(dict["CD2_2"], CultureInfo.InvariantCulture)
                );

            result.Success     = true;
            result.Coordinates = new Coordinates(
                double.Parse(dict["CRVAL1"], CultureInfo.InvariantCulture),
                double.Parse(dict["CRVAL2"], CultureInfo.InvariantCulture),
                Epoch.J2000,
                Coordinates.RAType.Degrees
                );

            result.Orientation = double.Parse(dict["CROTA2"], CultureInfo.InvariantCulture);

            /*
             * CDELT1 and CDELT2 are obsolete.
             * To calculate pixel scale, we should add the squares of CD1_2 and CD2_2 and take the square root to get degrees.
             */
            if (dict.ContainsKey("CD1_2") && dict.ContainsKey("CD2_2"))
            {
                double.TryParse(dict["CD1_2"], NumberStyles.Any, CultureInfo.InvariantCulture, out double cr1y);
                double.TryParse(dict["CD2_2"], NumberStyles.Any, CultureInfo.InvariantCulture, out double cr2y);

                result.Pixscale = Astrometry.DegreeToArcsec(Math.Sqrt(Math.Pow(cr1y, 2) + Math.Pow(cr2y, 2)));
            }

            /* Due to the way N.I.N.A. writes FITS files, the orientation is mirrored on the x-axis */
            result.Orientation = wcs.Rotation - 180;
            result.Flipped     = !wcs.Flipped;

            return(result);
        }