public static void ResetCoordinateSystem() { if (!(CameraSystem is WorldCoordinateSystem)) { CameraSystem = new WorldCoordinateSystem(); } //these axis values won't actually be used CameraSystem.AxisX = Vector3.right; CameraSystem.AxisY = Vector3.up; CameraSystem.AxisZ = Vector3.forward; CameraSystem.WorldPosition = MainCamera.transform.position; }
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); }
public ImageMetaData ExtractMetaData() { var metaData = new ImageMetaData(); if (_headerCards.ContainsKey("IMAGETYP")) { metaData.Image.ImageType = _headerCards["IMAGETYP"].OriginalValue; } if (_headerCards.TryGetValue("IMAGETYP", out var card)) { metaData.Image.ImageType = card.OriginalValue; } if (_headerCards.TryGetValue("EXPOSURE", out card)) { metaData.Image.ExposureTime = ParseDouble(card.OriginalValue); } if (_headerCards.TryGetValue("EXPTIME", out card)) { metaData.Image.ExposureTime = ParseDouble(card.OriginalValue); } if (_headerCards.TryGetValue("DATE-LOC", out card)) { //metaData.Image.ExposureStart = DateTime.ParseExact($"{card.OriginalValue}", "yyyy-MM-ddTHH:mm:ss.fff", CultureInfo.InvariantCulture); } if (_headerCards.TryGetValue("DATE-OBS", out card)) { //metaData.Image.ExposureStart = DateTime.ParseExact($"{card.OriginalValue} UTC", "yyyy-MM-ddTHH:mm:ss.fff UTC", CultureInfo.InvariantCulture); } /* Camera */ if (_headerCards.TryGetValue("XBINNING", out card)) { metaData.Camera.BinX = ParseInt(card.OriginalValue); } if (_headerCards.TryGetValue("YBINNING", out card)) { metaData.Camera.BinY = ParseInt(card.OriginalValue); } if (_headerCards.TryGetValue("GAIN", out card)) { metaData.Camera.Gain = ParseInt(card.OriginalValue); } if (_headerCards.TryGetValue("OFFSET", out card)) { metaData.Camera.Offset = ParseInt(card.OriginalValue); } if (_headerCards.TryGetValue("EGAIN", out card)) { metaData.Camera.ElectronsPerADU = ParseDouble(card.OriginalValue); } if (_headerCards.TryGetValue("XPIXSZ", out card)) { metaData.Camera.PixelSize = ParseDouble(card.OriginalValue) / metaData.Camera.BinX; } if (_headerCards.TryGetValue("INSTRUME", out card)) { metaData.Camera.Name = card.OriginalValue; } if (_headerCards.TryGetValue("SET-TEMP", out card)) { metaData.Camera.SetPoint = ParseDouble(card.OriginalValue); } if (_headerCards.TryGetValue("CCD-TEMP", out card)) { metaData.Camera.Temperature = ParseDouble(card.OriginalValue); } if (_headerCards.TryGetValue("READOUTM", out card)) { metaData.Camera.ReadoutModeName = card.OriginalValue; } if (_headerCards.TryGetValue("BAYERPAT", out card)) { metaData.Camera.SensorType = metaData.StringToSensorType(card.OriginalValue); } if (_headerCards.TryGetValue("XBAYROFF", out card)) { metaData.Camera.BayerOffsetX = ParseInt(card.OriginalValue); } if (_headerCards.TryGetValue("YBAYROFF", out card)) { metaData.Camera.BayerOffsetY = ParseInt(card.OriginalValue); } if (_headerCards.TryGetValue("USBLIMIT", out card)) { metaData.Camera.USBLimit = ParseInt(card.OriginalValue); } /* Telescope */ if (_headerCards.TryGetValue("TELESCOP", out card)) { metaData.Telescope.Name = card.OriginalValue; } if (_headerCards.TryGetValue("FOCALLEN", out card)) { metaData.Telescope.FocalLength = ParseDouble(card.OriginalValue); } if (_headerCards.TryGetValue("FOCRATIO", out card)) { metaData.Telescope.FocalRatio = ParseDouble(card.OriginalValue); } if (_headerCards.ContainsKey("RA") && _headerCards.ContainsKey("DEC")) { var ra = ParseDouble(_headerCards["RA"].OriginalValue); var dec = ParseDouble(_headerCards["DEC"].OriginalValue); metaData.Telescope.Coordinates = new Astrometry.Coordinates(Angle.ByDegree(ra), Angle.ByDegree(dec), Epoch.J2000); } /* Observer */ if (_headerCards.TryGetValue("SITEELEV", out card)) { metaData.Observer.Elevation = ParseDouble(card.OriginalValue); } if (_headerCards.TryGetValue("SITELAT", out card)) { metaData.Observer.Latitude = ParseDouble(card.OriginalValue); } if (_headerCards.TryGetValue("SITELONG", out card)) { metaData.Observer.Longitude = ParseDouble(card.OriginalValue); } /* Filter Wheel */ if (_headerCards.TryGetValue("FWHEEL", out card)) { metaData.FilterWheel.Name = card.OriginalValue; } if (_headerCards.TryGetValue("FILTER", out card)) { metaData.FilterWheel.Filter = card.OriginalValue; } /* Target */ if (_headerCards.TryGetValue("OBJECT", out card)) { metaData.Target.Name = card.OriginalValue; } if (_headerCards.ContainsKey("OBJCTRA") && _headerCards.ContainsKey("OBJCTDEC")) { var ra = Astrometry.Astrometry.HMSToDegrees(_headerCards["OBJCTRA"].OriginalValue); var dec = Astrometry.Astrometry.DMSToDegrees(_headerCards["OBJCTDEC"].OriginalValue); metaData.Target.Coordinates = new Astrometry.Coordinates(Angle.ByDegree(ra), Angle.ByDegree(dec), Epoch.J2000); } /* Focuser */ if (_headerCards.TryGetValue("FOCNAME", out card)) { metaData.Focuser.Name = card.OriginalValue; } if (_headerCards.TryGetValue("FOCPOS", out card)) { metaData.Focuser.Position = ParseDouble(card.OriginalValue); } if (_headerCards.TryGetValue("FOCUSPOS", out card)) { metaData.Focuser.Position = ParseDouble(card.OriginalValue); } if (_headerCards.TryGetValue("FOCUSSZ", out card)) { metaData.Focuser.StepSize = ParseDouble(card.OriginalValue); } if (_headerCards.TryGetValue("FOCTEMP", out card)) { metaData.Focuser.Temperature = ParseDouble(card.OriginalValue); } if (_headerCards.TryGetValue("FOCUSTEM", out card)) { metaData.Focuser.Temperature = ParseDouble(card.OriginalValue); } /* Rotator */ if (_headerCards.TryGetValue("ROTNAME", out card)) { metaData.Rotator.Name = card.OriginalValue; } if (_headerCards.TryGetValue("ROTATOR", out card)) { metaData.Rotator.MechanicalPosition = ParseDouble(card.OriginalValue); } if (_headerCards.TryGetValue("ROTATANG", out card)) { metaData.Rotator.MechanicalPosition = ParseDouble(card.OriginalValue); } if (_headerCards.TryGetValue("ROTSTPSZ", out card)) { metaData.Rotator.StepSize = ParseDouble(card.OriginalValue); } /* Weather Data */ if (_headerCards.TryGetValue("CLOUDCVR", out card)) { metaData.WeatherData.CloudCover = ParseDouble(card.OriginalValue); } if (_headerCards.TryGetValue("DEWPOINT", out card)) { metaData.WeatherData.DewPoint = ParseDouble(card.OriginalValue); } if (_headerCards.TryGetValue("HUMIDITY", out card)) { metaData.WeatherData.Humidity = ParseDouble(card.OriginalValue); } if (_headerCards.TryGetValue("PRESSURE", out card)) { metaData.WeatherData.Pressure = ParseDouble(card.OriginalValue); } if (_headerCards.TryGetValue("SKYBRGHT", out card)) { metaData.WeatherData.SkyBrightness = ParseDouble(card.OriginalValue); } if (_headerCards.TryGetValue("MPSAS", out card)) { metaData.WeatherData.SkyQuality = ParseDouble(card.OriginalValue); } if (_headerCards.TryGetValue("SKYTEMP", out card)) { metaData.WeatherData.SkyTemperature = ParseDouble(card.OriginalValue); } if (_headerCards.TryGetValue("STARFWHM", out card)) { metaData.WeatherData.StarFWHM = ParseDouble(card.OriginalValue); } if (_headerCards.TryGetValue("AMBTEMP", out card)) { metaData.WeatherData.Temperature = ParseDouble(card.OriginalValue); } if (_headerCards.TryGetValue("WINDDIR", out card)) { metaData.WeatherData.WindDirection = ParseDouble(card.OriginalValue); } if (_headerCards.TryGetValue("WINDGUST", out card)) { metaData.WeatherData.WindGust = ParseDouble(card.OriginalValue) / 3.6; } if (_headerCards.TryGetValue("WINDSPD", out card)) { metaData.WeatherData.WindSpeed = ParseDouble(card.OriginalValue) / 3.6; } /* WCS */ if (_headerCards.TryGetValue("CTYPE1", out var ctype1Card) && _headerCards.TryGetValue("CTYPE2", out var ctype2Card)) { if (ctype1Card.OriginalValue == "RA---TAN" && ctype2Card.OriginalValue == "DEC--TAN") { if (_headerCards.TryGetValue("CRPIX1", out var crpix1Card) && _headerCards.TryGetValue("CRPIX2", out var crpix2Card) && _headerCards.TryGetValue("CRVAL1", out var crval1Card) && _headerCards.TryGetValue("CRVAL2", out var crval2Card)) { var crPix1 = ParseDouble(crpix1Card.OriginalValue); var crPix2 = ParseDouble(crpix2Card.OriginalValue); var crVal1 = ParseDouble(crval1Card.OriginalValue); var crVal2 = ParseDouble(crval2Card.OriginalValue); if (_headerCards.TryGetValue("CD1_1", out var cd1_1Card) && _headerCards.TryGetValue("CD1_2", out var cd1_2Card) && _headerCards.TryGetValue("CD2_1", out var cd2_1Card) && _headerCards.TryGetValue("CD2_2", out var cd2_2Card) ) { // CDn_m notation var cd1_1 = ParseDouble(cd1_1Card.OriginalValue); var cd1_2 = ParseDouble(cd1_2Card.OriginalValue); var cd2_1 = ParseDouble(cd2_1Card.OriginalValue); var cd2_2 = ParseDouble(cd2_2Card.OriginalValue); var wcs = new WorldCoordinateSystem(crVal1, crVal2, crPix1, crPix2, cd1_1, cd1_2, cd2_1, cd2_2); metaData.WorldCoordinateSystem = wcs; } else if (_headerCards.TryGetValue("CDELT1", out var CDELT1Card) && _headerCards.TryGetValue("CDELT2", out var CDELT2Card) && _headerCards.TryGetValue("CROTA2", out var CROTA2Card) ) { // Older CROTA2 notation var cdelt1 = ParseDouble(CDELT1Card.OriginalValue); var cdelt2 = ParseDouble(CDELT2Card.OriginalValue); var crota2 = ParseDouble(CROTA2Card.OriginalValue); var wcs = new WorldCoordinateSystem(crVal1, crVal2, crPix1, crPix2, cdelt1, cdelt2, crota2); metaData.WorldCoordinateSystem = wcs; } else { Logger.Debug("FITS WCS - No CROTA2 or CDn_m keywords found"); } } else { Logger.Debug("FITS WCS - No CRPIX and CRVAL keywords found"); } } else { Logger.Debug($"FITS WCS - Incompatible projection found {ctype1Card.OriginalValue} {ctype2Card.OriginalValue}"); } } return(metaData); }
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); }