Beispiel #1
0
        public async Task Successful_Centering_NoSeparation_Test()
        {
            var seq         = new CaptureSequence();
            var coordinates = new Coordinates(Angle.ByDegree(5), Angle.ByDegree(3), Epoch.JNOW);
            var parameter   = new CenterSolveParameter()
            {
                Coordinates = coordinates.Transform(Epoch.JNOW),
                FocalLength = 700,
                Threshold   = 1
            };
            var testResult = new PlateSolveResult()
            {
                Success     = true,
                Coordinates = coordinates.Transform(Epoch.JNOW)
            };

            captureSolverMock
            .Setup(x => x.Solve(seq, It.IsAny <CaptureSolverParameter>(), It.IsAny <IProgress <PlateSolveProgress> >(), It.IsAny <IProgress <ApplicationStatus> >(), It.IsAny <CancellationToken>()))
            .ReturnsAsync(testResult);
            telescopeMediatorMock
            .Setup(x => x.GetCurrentPosition())
            .Returns(coordinates);

            var sut = new CenteringSolver(plateSolverMock.Object, blindSolverMock.Object, null, telescopeMediatorMock.Object);

            sut.CaptureSolver = captureSolverMock.Object;

            var result = await sut.Center(seq, parameter, default, default, default);
        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);
        }
Beispiel #3
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);
        }
Beispiel #4
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);
        }
Beispiel #5
0
        public async Task Successful_CaptureAndSolving_Test()
        {
            var imageDataMock     = new Mock <IImageData>();
            var renderedImageMock = new Mock <IRenderedImage>();

            renderedImageMock.SetupGet(x => x.RawImageData).Returns(imageDataMock.Object);
            var testResult = new PlateSolveResult()
            {
                Success = true
            };
            var seq       = new CaptureSequence();
            var parameter = new CaptureSolverParameter()
            {
                FocalLength = 700
            };

            imagingMediatorMock.Setup(x => x.CaptureAndPrepareImage(seq, It.IsAny <PrepareImageParameters>(), It.IsAny <CancellationToken>(), It.IsAny <IProgress <ApplicationStatus> >())).ReturnsAsync(renderedImageMock.Object);
            imageSolverMock.Setup(x => x.Solve(imageDataMock.Object, It.IsAny <PlateSolveParameter>(), It.IsAny <IProgress <ApplicationStatus> >(), It.IsAny <CancellationToken>())).ReturnsAsync(testResult);

            var sut = new CaptureSolver(plateSolverMock.Object, blindSolverMock.Object, imagingMediatorMock.Object);

            sut.ImageSolver = imageSolverMock.Object;

            var result = await sut.Solve(seq, parameter, default, default, default);
Beispiel #6
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);
        }
Beispiel #7
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);
        }
Beispiel #8
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);
        }