public ImageMetaData ExtractMetaData() { var metaData = new ImageMetaData(); if (TryGetImageProperty(XISFImageProperty.Observation.Time.Start, out var value)) { metaData.Image.ExposureStart = DateTime.Parse(value); } if (TryGetImageProperty(XISFImageProperty.Instrument.ExposureTime, out value)) { metaData.Image.ExposureTime = double.Parse(value, CultureInfo.InvariantCulture); } /* Camera */ if (TryGetImageProperty(XISFImageProperty.Instrument.Camera.Name, out value)) { metaData.Camera.Name = value; } if (TryGetFITSProperty("GAIN", out value)) { metaData.Camera.Gain = int.Parse(value, CultureInfo.InvariantCulture); } if (TryGetFITSProperty("OFFSET", out value)) { metaData.Camera.Offset = int.Parse(value, CultureInfo.InvariantCulture); } if (TryGetImageProperty(XISFImageProperty.Instrument.Camera.Gain, out value)) { metaData.Camera.ElectronsPerADU = double.Parse(value, CultureInfo.InvariantCulture); } if (TryGetImageProperty(XISFImageProperty.Instrument.Camera.XBinning, out value)) { metaData.Camera.BinX = int.Parse(value, CultureInfo.InvariantCulture); } if (TryGetImageProperty(XISFImageProperty.Instrument.Camera.YBinning, out value)) { metaData.Camera.BinY = int.Parse(value, CultureInfo.InvariantCulture); } if (TryGetImageProperty(XISFImageProperty.Instrument.Sensor.Temperature, out value)) { metaData.Camera.Temperature = double.Parse(value, CultureInfo.InvariantCulture); } if (TryGetFITSProperty("SET-TEMP", out value)) { metaData.Camera.SetPoint = double.Parse(value, CultureInfo.InvariantCulture); } if (TryGetImageProperty(XISFImageProperty.Instrument.Sensor.XPixelSize, out value)) { metaData.Camera.PixelSize = double.Parse(value, CultureInfo.InvariantCulture) / metaData.Camera.BinX; } if (TryGetFITSProperty("READOUTM", out value)) { metaData.Camera.ReadoutModeName = value; } if (TryGetFITSProperty("BAYERPAT", out value)) { metaData.Camera.SensorType = metaData.StringToSensorType(value); } if (TryGetFITSProperty("XBAYEROFF", out value)) { metaData.Camera.BayerOffsetX = int.Parse(value, CultureInfo.InvariantCulture); } if (TryGetFITSProperty("YBAYEROFF", out value)) { metaData.Camera.BayerOffsetY = int.Parse(value, CultureInfo.InvariantCulture); } if (TryGetFITSProperty("USBLIMIT", out value)) { metaData.Camera.USBLimit = int.Parse(value, CultureInfo.InvariantCulture); } /* Observer */ if (TryGetImageProperty(XISFImageProperty.Observation.Location.Elevation, out value)) { metaData.Observer.Elevation = double.Parse(value, CultureInfo.InvariantCulture); } if (TryGetImageProperty(XISFImageProperty.Observation.Location.Latitude, out value)) { metaData.Observer.Latitude = double.Parse(value, CultureInfo.InvariantCulture); } if (TryGetImageProperty(XISFImageProperty.Observation.Location.Longitude, out value)) { metaData.Observer.Longitude = double.Parse(value, CultureInfo.InvariantCulture); } /* Telescope */ if (TryGetImageProperty(XISFImageProperty.Instrument.Telescope.Name, out value)) { metaData.Telescope.Name = value; } if (TryGetImageProperty(XISFImageProperty.Instrument.Telescope.FocalLength, out value)) { metaData.Telescope.FocalLength = double.Parse(value, CultureInfo.InvariantCulture) * 1e3; } if (TryGetImageProperty(XISFImageProperty.Instrument.Telescope.Aperture, out value)) { metaData.Telescope.FocalRatio = double.Parse(value, CultureInfo.InvariantCulture) * 1e3 / metaData.Telescope.FocalLength; } if (TryGetImageProperty(XISFImageProperty.Observation.Center.RA, out value)) { var ra = double.Parse(value, CultureInfo.InvariantCulture); if (TryGetImageProperty(XISFImageProperty.Observation.Center.Dec, out value)) { var dec = double.Parse(value, CultureInfo.InvariantCulture); metaData.Telescope.Coordinates = new Coordinates(Angle.ByDegree(ra), Angle.ByDegree(dec), Epoch.J2000); } } /* Target */ if (TryGetImageProperty(XISFImageProperty.Observation.Object.Name, out value)) { metaData.Target.Name = value; } if (TryGetImageProperty(XISFImageProperty.Observation.Object.RA, out value)) { var ra = double.Parse(value, CultureInfo.InvariantCulture); if (TryGetImageProperty(XISFImageProperty.Observation.Object.Dec, out value)) { var dec = double.Parse(value, CultureInfo.InvariantCulture); metaData.Telescope.Coordinates = new Coordinates(Angle.ByDegree(ra), Angle.ByDegree(dec), Epoch.J2000); } } /* Focuser */ if (TryGetFITSProperty("FOCNAME", out value)) { metaData.Focuser.Name = value; } /* Filter */ if (TryGetImageProperty(XISFImageProperty.Instrument.Filter.Name, out value)) { metaData.FilterWheel.Filter = value; } /* Weather Data */ if (TryGetImageProperty(XISFImageProperty.Observation.Meteorology.RelativeHumidity, out value)) { metaData.WeatherData.Humidity = double.Parse(value, CultureInfo.InvariantCulture); } if (TryGetImageProperty(XISFImageProperty.Observation.Meteorology.AtmosphericPressure, out value)) { metaData.WeatherData.Pressure = double.Parse(value, CultureInfo.InvariantCulture); } if (TryGetImageProperty(XISFImageProperty.Observation.Meteorology.AmbientTemperature, out value)) { metaData.WeatherData.Temperature = double.Parse(value, CultureInfo.InvariantCulture); } if (TryGetImageProperty(XISFImageProperty.Observation.Meteorology.WindDirection, out value)) { metaData.WeatherData.WindDirection = double.Parse(value, CultureInfo.InvariantCulture); } if (TryGetImageProperty(XISFImageProperty.Observation.Meteorology.WindGust, out value)) { metaData.WeatherData.WindGust = double.Parse(value, CultureInfo.InvariantCulture); } if (TryGetImageProperty(XISFImageProperty.Observation.Meteorology.WindSpeed, out value)) { metaData.WeatherData.WindSpeed = double.Parse(value, CultureInfo.InvariantCulture); } /* WCS */ if (TryGetFITSProperty("CTYPE1", out var ctype1) && TryGetFITSProperty("CTYPE2", out var ctype2)) { if (ctype1 == "RA---TAN" && ctype2 == "DEC--TAN") { if (TryGetFITSProperty("CRPIX1", out var CRPIX1Value) && TryGetFITSProperty("CRPIX2", out var CRPIX2Value) && TryGetFITSProperty("CRVAL1", out var CRVAL1Value) && TryGetFITSProperty("CRVAL2", out var CRVAL2Value) ) { var crPix1 = double.Parse(CRPIX1Value, CultureInfo.InvariantCulture); var crPix2 = double.Parse(CRPIX2Value, CultureInfo.InvariantCulture); var crVal1 = double.Parse(CRVAL1Value, CultureInfo.InvariantCulture); var crVal2 = double.Parse(CRVAL2Value, CultureInfo.InvariantCulture); if (TryGetFITSProperty("CD1_1", out var CD1_1Value) && TryGetFITSProperty("CD2_1", out var CD2_1Value) && TryGetFITSProperty("CD1_2", out var CD1_2Value) && TryGetFITSProperty("CD2_2", out var CD2_2Value) ) { // CDn_m notation var cd1_1 = double.Parse(CD1_1Value, CultureInfo.InvariantCulture); var cd2_1 = double.Parse(CD2_1Value, CultureInfo.InvariantCulture); var cd1_2 = double.Parse(CD1_2Value, CultureInfo.InvariantCulture); var cd2_2 = double.Parse(CD2_2Value, CultureInfo.InvariantCulture); var wcs = new WorldCoordinateSystem(crVal1, crVal2, crPix1, crPix2, cd1_1, cd1_2, cd2_1, cd2_2); metaData.WorldCoordinateSystem = wcs; } else if (TryGetFITSProperty("CDELT1", out var CDELT1Value) && TryGetFITSProperty("CDELT2", out var CDELT2Value) && TryGetFITSProperty("CROTA2", out var CROTA2Value) ) { // Older CROTA2 notation var cdelt1 = double.Parse(CDELT1Value, CultureInfo.InvariantCulture); var cdelt2 = double.Parse(CDELT2Value, CultureInfo.InvariantCulture); var crota2 = double.Parse(CROTA2Value, CultureInfo.InvariantCulture); var wcs = new WorldCoordinateSystem(crVal1, crVal2, crPix1, crPix2, cdelt1, cdelt2, crota2); metaData.WorldCoordinateSystem = wcs; } else { Logger.Debug("XISF WCS - No CROTA2 or CDn_m keywords found"); } } else { Logger.Debug("XISF WCS - No CRPIX and CRVAL keywords found"); } } else { Logger.Debug($"XISF WCS - Incompatible projection found {ctype1} {ctype2}"); } } return(metaData); }
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); }