public ViewportFoV(Coordinates centerCoordinates, double vFoVDegrees, double width, double height, double rotation) { Rotation = rotation; OriginalWidth = width; OriginalHeight = height; Width = width; Height = height; OriginalVFoV = vFoVDegrees; OriginalHFoV = (vFoVDegrees / height) * width; ArcSecWidth = Astrometry.DegreeToArcsec(OriginalHFoV) / OriginalWidth; ArcSecHeight = Astrometry.DegreeToArcsec(OriginalVFoV) / OriginalHeight; CenterCoordinates = centerCoordinates; ViewPortCenterPoint = new Point(width / 2, height / 2); Shift(new Vector(0, 0)); horizontalBoundsPadding = Width / 6; verticalBoundsPadding = Height / 6; }
public void DegreeToArcsec_ValueTest() { var degree = 180; var expectedarcsec = 648000; var arcsec = Astrometry.DegreeToArcsec(degree); Assert.AreEqual(expectedarcsec, arcsec); }
public void CreateByRadiansTest(double inputRadians) { var angle = Angle.ByRadians(inputRadians); var expectedDegree = Astrometry.ToDegree(inputRadians); var expectedArcmin = Astrometry.DegreeToArcmin(expectedDegree); var expectedArcsec = Astrometry.DegreeToArcsec(expectedDegree); var expectedHours = Astrometry.DegreesToHours(expectedDegree); Assert.AreEqual(expectedHours, angle.Hours, TOLERANCE); Assert.AreEqual(inputRadians, angle.Radians, TOLERANCE); Assert.AreEqual(expectedDegree, angle.Degree, TOLERANCE); Assert.AreEqual(expectedArcmin, angle.ArcMinutes, TOLERANCE); Assert.AreEqual(expectedArcsec, angle.ArcSeconds, TOLERANCE); }
private string Deg2str(double deg, int precision) { if (Math.Abs(deg) > 1) { return(deg.ToString("N" + precision) + "° (degree)"); } var amin = Astrometry.DegreeToArcmin(deg); if (Math.Abs(amin) > 1) { return(amin.ToString("N" + precision) + "' (arcmin)"); } var asec = Astrometry.DegreeToArcsec(deg); return(asec.ToString("N" + precision) + "'' (arcsec)"); }
public void OperatorMultiplyDoubleTest(double firstDegree, double secondDegree) { var secondAngle = Angle.ByDegree(secondDegree); var angle = Astrometry.ToRadians(firstDegree) * secondAngle; var expectedRadian = Astrometry.ToRadians(firstDegree) * Astrometry.ToRadians(secondDegree); var expectedDegree = Astrometry.ToDegree(expectedRadian); var expectedArcmin = Astrometry.DegreeToArcmin(expectedDegree); var expectedArcsec = Astrometry.DegreeToArcsec(expectedDegree); var expectedHours = Astrometry.DegreesToHours(expectedDegree); Assert.AreEqual(expectedDegree, angle.Degree, TOLERANCE); Assert.AreEqual(expectedArcmin, angle.ArcMinutes, TOLERANCE); Assert.AreEqual(expectedArcsec, angle.ArcSeconds, TOLERANCE); Assert.AreEqual(expectedHours, angle.Hours, TOLERANCE); Assert.AreEqual(expectedRadian, angle.Radians, TOLERANCE); }
public void StaticAtan2Test(double xRadians, double yRadians) { var xAngle = Angle.ByRadians(xRadians); var yAngle = Angle.ByRadians(yRadians); var angle = Angle.Atan2(yAngle, xAngle); var rad = Math.Atan2(yRadians, xRadians); var expectedDegree = Astrometry.ToDegree(rad); var expectedArcmin = Astrometry.DegreeToArcmin(expectedDegree); var expectedArcsec = Astrometry.DegreeToArcsec(expectedDegree); var expectedHours = Astrometry.DegreesToHours(expectedDegree); Assert.AreEqual(expectedHours, angle.Hours, TOLERANCE); Assert.AreEqual(rad, angle.Radians, TOLERANCE); Assert.AreEqual(expectedDegree, angle.Degree, TOLERANCE); Assert.AreEqual(expectedArcmin, angle.ArcMinutes, TOLERANCE); Assert.AreEqual(expectedArcsec, angle.ArcSeconds, TOLERANCE); }
public async Task <PlateSolveResult> Center(CaptureSequence seq, CenterSolveParameter parameter, IProgress <PlateSolveProgress> solveProgress, IProgress <ApplicationStatus> progress, CancellationToken ct) { if (parameter?.Coordinates == null) { throw new ArgumentException(nameof(CenterSolveParameter.Coordinates)); } if (parameter?.Threshold <= 0) { throw new ArgumentException(nameof(CenterSolveParameter.Threshold)); } var centered = false; PlateSolveResult result; Separation offset = new Separation(); do { result = await CaptureSolver.Solve(seq, parameter, solveProgress, progress, ct); if (result.Success == false) { //Solving failed. Give up. break; } var position = (telescopeMediator.GetCurrentPosition() - offset).Transform(result.Coordinates.Epoch); result.Separation = result.DetermineSeparation(position); Logger.Debug($"Centering Solver - Scope Position: {position}; Centering Coordinates: {parameter.Coordinates}; Solve Result: {result.Coordinates}; Separation {result.Separation}"); solveProgress?.Report(new PlateSolveProgress() { PlateSolveResult = result }); if (Math.Abs(result.Separation.Distance.ArcMinutes) > parameter.Threshold) { progress?.Report(new ApplicationStatus() { Status = Locale.Loc.Instance["LblPlateSolveNotInsideToleranceSyncing"] }); if (parameter.NoSync || !await telescopeMediator.Sync(result.Coordinates)) { offset = result.DetermineSeparation(position + offset); Logger.Debug($"Sync failed - calculating offset instead to compensate. Original: {position.Transform(result.Coordinates.Epoch)}; Solved: {result.Coordinates}; Offset: {offset}"); progress?.Report(new ApplicationStatus() { Status = Locale.Loc.Instance["LblPlateSolveSyncViaTargetOffset"] }); } else { var positionAfterSync = telescopeMediator.GetCurrentPosition().Transform(result.Coordinates.Epoch); if (Astrometry.DegreeToArcsec(Math.Abs(positionAfterSync.RADegrees - result.Coordinates.RADegrees)) > 1 || Astrometry.DegreeToArcsec(Math.Abs(positionAfterSync.Dec - result.Coordinates.Dec)) > 1) { offset = result.DetermineSeparation(positionAfterSync); Logger.Debug($"Sync failed silently - calculating offset instead to compensate. Original: {positionAfterSync}; Solved: {result.Coordinates}; Offset: {offset}"); } else { // Sync worked - reset offset Logger.Debug("Synced sucessfully"); offset = new Separation(); } } Logger.Trace($"Slewing to target after sync. Target coordinates RA: {parameter.Coordinates.RAString} Dec: {parameter.Coordinates.DecString} Epoch: {parameter.Coordinates.Epoch}"); progress?.Report(new ApplicationStatus() { Status = Locale.Loc.Instance["LblPlateSolveNotInsideToleranceReslew"] }); await telescopeMediator.SlewToCoordinatesAsync(parameter.Coordinates + offset); progress?.Report(new ApplicationStatus() { Status = Locale.Loc.Instance["LblPlateSolveNotInsideToleranceRepeating"] }); } else { centered = true; } } while (!centered); return(result); }
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); }