public static void Initialize() { lock (lockObj) { if (!initialized) { if (!DllLoader.IsX86()) { //When EOS Utility by Canon is open in the background the EDSDK.EdsInitializeSDK throws an uncatchable AccessViolation Exception //Therefore the system processes are scanned for this program and if found the initialization is prevented var eosUtil = System.Diagnostics.Process.GetProcessesByName("EOS Utility"); if (eosUtil.Length > 0) { throw new Exception("Cannot initialize Canon SDK. EOS Utiltiy is preventing the DLL to load. Please close EOS Utility first to be able to connect to your Canon Camera!"); } } var err = EDSDK.EdsInitializeSDK(); if (err > 0) { throw new Exception($"Canon EdsInitializeSDK failed with code {err}"); } else { initialized = true; } } } }
public void Populate(ImageMetaData metaData) { if (metaData.Image.ExposureStart > DateTime.MinValue) { AddImageProperty(XISFImageProperty.Observation.Time.Start, metaData.Image.ExposureStart.ToUniversalTime(), "Time of observation (UTC)"); AddImageFITSKeyword("DATE-LOC", metaData.Image.ExposureStart.ToLocalTime(), "Time of observation (local)"); } if (!double.IsNaN(metaData.Image.ExposureTime)) { AddImageProperty(XISFImageProperty.Instrument.ExposureTime, metaData.Image.ExposureTime, "[s] Exposure duration"); AddImageFITSKeyword("EXPTIME", metaData.Image.ExposureTime, "[s] Exposure duration"); } /* Camera */ if (!string.IsNullOrWhiteSpace(metaData.Camera.Name)) { AddImageProperty(XISFImageProperty.Instrument.Camera.Name, metaData.Camera.Name, "Imaging instrument name"); } if (metaData.Camera.Gain >= 0) { AddImageFITSKeyword("GAIN", metaData.Camera.Gain, "Sensor gain"); } if (metaData.Camera.Offset >= 0) { AddImageFITSKeyword("OFFSET", metaData.Camera.Offset, "Sensor gain offset"); } if (!double.IsNaN(metaData.Camera.ElectronsPerADU)) { AddImageProperty(XISFImageProperty.Instrument.Camera.Gain, metaData.Camera.ElectronsPerADU, "[e-/ADU] Electrons per A/D unit"); } if (metaData.Camera.BinX > 0) { AddImageProperty(XISFImageProperty.Instrument.Camera.XBinning, metaData.Camera.BinX, "X axis binning factor"); } if (metaData.Camera.BinY > 0) { AddImageProperty(XISFImageProperty.Instrument.Camera.YBinning, metaData.Camera.BinY, "Y axis binning factor"); } if (!double.IsNaN(metaData.Camera.SetPoint)) { AddImageFITSKeyword("SET-TEMP", metaData.Camera.SetPoint, "[degC] CCD temperature setpoint"); } if (!double.IsNaN(metaData.Camera.Temperature)) { AddImageProperty(XISFImageProperty.Instrument.Sensor.Temperature, metaData.Camera.Temperature, "[degC] CCD temperature"); } if (!double.IsNaN(metaData.Camera.PixelSize)) { double pixelX = metaData.Camera.PixelSize * Math.Max(metaData.Camera.BinX, 1); double pixelY = metaData.Camera.PixelSize * Math.Max(metaData.Camera.BinY, 1); AddImageProperty(XISFImageProperty.Instrument.Sensor.XPixelSize, pixelX, "[um] Pixel X axis size"); AddImageProperty(XISFImageProperty.Instrument.Sensor.YPixelSize, pixelY, "[um] Pixel Y axis size"); } if (!string.IsNullOrWhiteSpace(metaData.Camera.ReadoutModeName)) { AddImageFITSKeyword("READOUTM", metaData.Camera.ReadoutModeName, "Sensor readout mode"); } if (metaData.Camera.SensorType != SensorType.Monochrome) { AddImageFITSKeyword("BAYERPAT", metaData.Camera.SensorType.ToString().ToUpper(), "Sensor Bayer pattern"); AddImageFITSKeyword("XBAYROFF", metaData.Camera.BayerOffsetX, "Bayer pattern X axis offset"); AddImageFITSKeyword("YBAYROFF", metaData.Camera.BayerOffsetY, "Bayer pattern Y axis offset"); /* * Add XISF ColorFilterArray element. We support only 2x2 bayer patterns for now. */ AddCfaAttribute(metaData.Camera.SensorType.ToString().ToUpper(), 2, 2); } if (metaData.Camera.USBLimit > -1) { AddImageFITSKeyword("USBLIMIT", metaData.Camera.USBLimit, "Camera-specific USB setting"); } /* Observer */ if (!double.IsNaN(metaData.Observer.Elevation)) { AddImageProperty(XISFImageProperty.Observation.Location.Elevation, metaData.Observer.Elevation, "[m] Observation site elevation"); } if (!double.IsNaN(metaData.Observer.Latitude)) { AddImageProperty(XISFImageProperty.Observation.Location.Latitude, metaData.Observer.Latitude, "[deg] Observation site latitude"); } if (!double.IsNaN(metaData.Observer.Longitude)) { AddImageProperty(XISFImageProperty.Observation.Location.Longitude, metaData.Observer.Longitude, "[deg] Observation site longitude"); } /* Telescope */ if (!string.IsNullOrWhiteSpace(metaData.Telescope.Name)) { AddImageProperty(XISFImageProperty.Instrument.Telescope.Name, metaData.Telescope.Name, "Name of telescope"); } if (!double.IsNaN(metaData.Telescope.FocalLength) && metaData.Telescope.FocalLength > 0) { AddImageProperty(XISFImageProperty.Instrument.Telescope.FocalLength, metaData.Telescope.FocalLength / 1e3, "[m] Focal Length"); AddImageFITSKeyword("FOCALLEN", metaData.Telescope.FocalLength, "[mm] Focal length"); if (!double.IsNaN(metaData.Telescope.FocalRatio) && metaData.Telescope.FocalRatio > 0) { double aperture = (metaData.Telescope.FocalLength / metaData.Telescope.FocalRatio) / 1e3; AddImageProperty(XISFImageProperty.Instrument.Telescope.Aperture, aperture, "[m] Aperture", false); AddImageFITSKeyword("FOCRATIO", metaData.Telescope.FocalRatio, "Focal ratio"); } } if (metaData.Telescope.Coordinates != null) { AddImageProperty(XISFImageProperty.Observation.Center.RA, metaData.Telescope.Coordinates.RADegrees, "[deg] RA of telescope"); AddImageProperty(XISFImageProperty.Observation.Center.Dec, metaData.Telescope.Coordinates.Dec, "[deg] Declination of telescope"); } /* Target */ if (!string.IsNullOrWhiteSpace(metaData.Target.Name)) { AddImageProperty(XISFImageProperty.Observation.Object.Name, metaData.Target.Name, "Name of the object of interest"); } if (metaData.Target.Coordinates != null) { AddImageProperty(XISFImageProperty.Observation.Object.RA, metaData.Target.Coordinates.RADegrees, "[deg] RA of imaged object", false); AddImageFITSKeyword(XISFImageProperty.Observation.Object.RA[2], Astrometry.Astrometry.HoursToFitsHMS(metaData.Target.Coordinates.RA), "[H M S] RA of imaged object"); AddImageProperty(XISFImageProperty.Observation.Object.Dec, metaData.Target.Coordinates.Dec, "[deg] Declination of imaged object", false); AddImageFITSKeyword(XISFImageProperty.Observation.Object.Dec[2], Astrometry.Astrometry.DegreesToFitsDMS(metaData.Target.Coordinates.Dec), "[D M S] Declination of imaged object"); } /* Focuser */ if (!string.IsNullOrWhiteSpace(metaData.Focuser.Name)) { /* fits4win, SGP */ AddImageFITSKeyword("FOCNAME", metaData.Focuser.Name, "Focusing equipment name"); } /* * XISF 1.0 defines Instrument:Focuser:Position as the only focuser-related image property. * This image property is: "(Float32) Estimated position of the focuser in millimetres, measured with respect to a device-dependent origin." * This unit is different from FOCUSPOS FITSKeyword, so we must do two separate actions: calculate distance from origin in millimetres and insert * that as the XISF Instrument:Focuser:Position property, and then insert the separate FOCUSPOS FITSKeyword (measured in steps). */ if (!double.IsNaN(metaData.Focuser.Position)) { if (!double.IsNaN(metaData.Focuser.StepSize)) { /* steps * step size (microns) converted to millimetres, single-precision float */ float focusDistance = (float)((metaData.Focuser.Position * metaData.Focuser.StepSize) / 1000.0); AddImageProperty(XISFImageProperty.Instrument.Focuser.Position, focusDistance); } /* fits4win, SGP */ AddImageFITSKeyword("FOCPOS", metaData.Focuser.Position, "[step] Focuser position"); /* MaximDL, several observatories */ AddImageFITSKeyword("FOCUSPOS", metaData.Focuser.Position, "[step] Focuser position"); } if (!double.IsNaN(metaData.Focuser.StepSize)) { /* MaximDL */ AddImageFITSKeyword("FOCUSSZ", metaData.Focuser.StepSize, "[um] Focuser step size"); } if (!double.IsNaN(metaData.Focuser.Temperature)) { /* fits4win, SGP */ AddImageFITSKeyword("FOCTEMP", metaData.Focuser.Temperature, "[degC] Focuser temperature"); /* MaximDL, several observatories */ AddImageFITSKeyword("FOCUSTEM", metaData.Focuser.Temperature, "[degC] Focuser temperature"); } /* Rotator */ if (!string.IsNullOrWhiteSpace(metaData.Rotator.Name)) { /* NINA */ AddImageFITSKeyword("ROTNAME", metaData.Rotator.Name, "Rotator equipment name"); } if (!double.IsNaN(metaData.Rotator.MechanicalPosition)) { /* fits4win */ AddImageFITSKeyword("ROTATOR", metaData.Rotator.MechanicalPosition, "[deg] Mechanical rotator angle"); /* MaximDL, several observatories */ AddImageFITSKeyword("ROTATANG", metaData.Rotator.MechanicalPosition, "[deg] Mechanical rotator angle"); } if (!double.IsNaN(metaData.Rotator.StepSize)) { /* NINA */ AddImageFITSKeyword("ROTSTPSZ", metaData.Rotator.StepSize, "[deg] Rotator step size"); } if (!string.IsNullOrWhiteSpace(metaData.FilterWheel.Name)) { /* fits4win */ AddImageFITSKeyword("FWHEEL", metaData.FilterWheel.Name, "Filter Wheel name"); } if (!string.IsNullOrWhiteSpace(metaData.FilterWheel.Filter)) { /* fits4win */ AddImageProperty(XISFImageProperty.Instrument.Filter.Name, metaData.FilterWheel.Filter, "Active filter name"); } /* Weather Data */ if (!double.IsNaN(metaData.WeatherData.CloudCover)) { AddImageFITSKeyword("CLOUDCVR", metaData.WeatherData.CloudCover, "[percent] Cloud cover"); } if (!double.IsNaN(metaData.WeatherData.DewPoint)) { AddImageFITSKeyword("DEWPOINT", metaData.WeatherData.DewPoint, "[degC] Dew point"); } if (!double.IsNaN(metaData.WeatherData.Humidity)) { AddImageProperty(XISFImageProperty.Observation.Meteorology.RelativeHumidity, metaData.WeatherData.Humidity, "[percent] Relative humidity"); } if (!double.IsNaN(metaData.WeatherData.Pressure)) { AddImageProperty(XISFImageProperty.Observation.Meteorology.AtmosphericPressure, metaData.WeatherData.Pressure, "[hPa] Air pressure"); } if (!double.IsNaN(metaData.WeatherData.SkyBrightness)) { AddImageFITSKeyword("SKYBRGHT", metaData.WeatherData.SkyBrightness, "[lux] Sky brightness"); } if (!double.IsNaN(metaData.WeatherData.SkyQuality)) { /* fits4win */ AddImageFITSKeyword("MPSAS", metaData.WeatherData.SkyQuality, "[mags/arcsec^2] Sky quality"); } if (!double.IsNaN(metaData.WeatherData.SkyTemperature)) { AddImageFITSKeyword("SKYTEMP", metaData.WeatherData.SkyTemperature, "[degC] Sky temperature"); } if (!double.IsNaN(metaData.WeatherData.StarFWHM)) { AddImageFITSKeyword("STARFWHM", metaData.WeatherData.StarFWHM, "Star FWHM"); } if (!double.IsNaN(metaData.WeatherData.Temperature)) { AddImageProperty(XISFImageProperty.Observation.Meteorology.AmbientTemperature, metaData.WeatherData.Temperature, "[degC] Ambient air temperature"); } if (!double.IsNaN(metaData.WeatherData.WindDirection)) { AddImageProperty(XISFImageProperty.Observation.Meteorology.WindDirection, metaData.WeatherData.WindDirection, "[deg] Wind direction: 0=N, 180=S, 90=E, 270=W"); } if (!double.IsNaN(metaData.WeatherData.WindGust)) { AddImageProperty(XISFImageProperty.Observation.Meteorology.WindGust, metaData.WeatherData.WindGust * 3.6, "[kph] Wind gust"); } if (!double.IsNaN(metaData.WeatherData.WindSpeed)) { AddImageProperty(XISFImageProperty.Observation.Meteorology.WindSpeed, metaData.WeatherData.WindSpeed * 3.6, "[kph] Wind speed"); } AddImageProperty(XISFImageProperty.Observation.Equinox, 2000d, "Equinox of celestial coordinate system"); AddImageFITSKeyword("SWCREATE", string.Format("N.I.N.A. {0} ({1})", Utility.Version, DllLoader.IsX86() ? "x86" : "x64"), "Software that created this file"); }
/// <summary> /// Fills FITS Header Cards using all available ImageMetaData information /// </summary> /// <param name="metaData"></param> public void PopulateFromMetaData(ImageMetaData metaData) { if (!string.IsNullOrWhiteSpace(metaData.Image.ImageType)) { var imageType = metaData.Image.ImageType; if (imageType == "SNAPSHOT") { imageType = "LIGHT"; } Add("IMAGETYP", imageType, "Type of exposure"); } if (!double.IsNaN(metaData.Image.ExposureTime)) { Add("EXPOSURE", metaData.Image.ExposureTime, "[s] Exposure duration"); Add("EXPTIME", metaData.Image.ExposureTime, "[s] Exposure duration"); } if (metaData.Image.ExposureStart > DateTime.MinValue) { Add("DATE-LOC", metaData.Image.ExposureStart.ToLocalTime(), "Time of observation (local)"); Add("DATE-OBS", metaData.Image.ExposureStart.ToUniversalTime(), "Time of observation (UTC)"); } /* Camera */ if (metaData.Camera.BinX > 0) { Add("XBINNING", metaData.Camera.BinX, "X axis binning factor"); } if (metaData.Camera.BinY > 0) { Add("YBINNING", metaData.Camera.BinY, "Y axis binning factor"); } if (metaData.Camera.Gain >= 0) { Add("GAIN", metaData.Camera.Gain, "Sensor gain"); } if (metaData.Camera.Offset >= 0) { Add("OFFSET", metaData.Camera.Offset, "Sensor gain offset"); } if (!double.IsNaN(metaData.Camera.ElectronsPerADU)) { Add("EGAIN", metaData.Camera.ElectronsPerADU, "[e-/ADU] Electrons per A/D unit"); } if (!double.IsNaN(metaData.Camera.PixelSize)) { double pixelX = metaData.Camera.PixelSize * Math.Max(metaData.Camera.BinX, 1); double pixelY = metaData.Camera.PixelSize * Math.Max(metaData.Camera.BinY, 1); Add("XPIXSZ", pixelX, "[um] Pixel X axis size"); Add("YPIXSZ", pixelY, "[um] Pixel Y axis size"); } if (!string.IsNullOrEmpty(metaData.Camera.Name)) { Add("INSTRUME", metaData.Camera.Name, "Imaging instrument name"); } if (!double.IsNaN(metaData.Camera.SetPoint)) { Add("SET-TEMP", metaData.Camera.SetPoint, "[degC] CCD temperature setpoint"); } if (!double.IsNaN(metaData.Camera.Temperature)) { Add("CCD-TEMP", metaData.Camera.Temperature, "[degC] CCD temperature"); } if (!string.IsNullOrWhiteSpace(metaData.Camera.ReadoutModeName)) { Add("READOUTM", metaData.Camera.ReadoutModeName, "Sensor readout mode"); } if (metaData.Camera.SensorType != SensorType.Monochrome) { Add("BAYERPAT", metaData.Camera.SensorType.ToString().ToUpper(), "Sensor Bayer pattern"); Add("XBAYROFF", metaData.Camera.BayerOffsetX, "Bayer pattern X axis offset"); Add("YBAYROFF", metaData.Camera.BayerOffsetY, "Bayer pattern Y axis offset"); } if (metaData.Camera.USBLimit > -1) { Add("USBLIMIT", metaData.Camera.USBLimit, "Camera-specific USB setting"); } /* Telescope */ if (!string.IsNullOrWhiteSpace(metaData.Telescope.Name)) { Add("TELESCOP", metaData.Telescope.Name, "Name of telescope"); } if (!double.IsNaN(metaData.Telescope.FocalLength) && metaData.Telescope.FocalLength > 0) { Add("FOCALLEN", metaData.Telescope.FocalLength, "[mm] Focal length"); } if (!double.IsNaN(metaData.Telescope.FocalRatio) && metaData.Telescope.FocalRatio > 0) { Add("FOCRATIO", metaData.Telescope.FocalRatio, "Focal ratio"); } if (metaData.Telescope.Coordinates != null) { Add("RA", metaData.Telescope.Coordinates.RADegrees, "[deg] RA of telescope"); Add("DEC", metaData.Telescope.Coordinates.Dec, "[deg] Declination of telescope"); } /* Observer */ if (!double.IsNaN(metaData.Observer.Elevation)) { Add("SITEELEV", metaData.Observer.Elevation, "[m] Observation site elevation"); } if (!double.IsNaN(metaData.Observer.Elevation)) { Add("SITELAT", metaData.Observer.Latitude, "[deg] Observation site latitude"); } if (!double.IsNaN(metaData.Observer.Elevation)) { Add("SITELONG", metaData.Observer.Longitude, "[deg] Observation site longitude"); } /* Filter Wheel */ if (!string.IsNullOrWhiteSpace(metaData.FilterWheel.Name)) { /* fits4win */ Add("FWHEEL", metaData.FilterWheel.Name, "Filter Wheel name"); } if (!string.IsNullOrWhiteSpace(metaData.FilterWheel.Filter)) { /* fits4win */ Add("FILTER", metaData.FilterWheel.Filter, "Active filter name"); } /* Target */ if (!string.IsNullOrWhiteSpace(metaData.Target.Name)) { Add("OBJECT", metaData.Target.Name, "Name of the object of interest"); } if (metaData.Target.Coordinates != null) { Add("OBJCTRA", Astrometry.Astrometry.HoursToFitsHMS(metaData.Target.Coordinates.RA), "[H M S] RA of imaged object"); Add("OBJCTDEC", Astrometry.Astrometry.DegreesToFitsDMS(metaData.Target.Coordinates.Dec), "[D M S] Declination of imaged object"); } /* Focuser */ if (!string.IsNullOrWhiteSpace(metaData.Focuser.Name)) { /* fits4win, SGP */ Add("FOCNAME", metaData.Focuser.Name, "Focusing equipment name"); } if (!double.IsNaN(metaData.Focuser.Position)) { /* fits4win, SGP */ Add("FOCPOS", metaData.Focuser.Position, "[step] Focuser position"); /* MaximDL, several observatories */ Add("FOCUSPOS", metaData.Focuser.Position, "[step] Focuser position"); } if (!double.IsNaN(metaData.Focuser.StepSize)) { /* MaximDL */ Add("FOCUSSZ", metaData.Focuser.StepSize, "[um] Focuser step size"); } if (!double.IsNaN(metaData.Focuser.Temperature)) { /* fits4win, SGP */ Add("FOCTEMP", metaData.Focuser.Temperature, "[degC] Focuser temperature"); /* MaximDL, several observatories */ Add("FOCUSTEM", metaData.Focuser.Temperature, "[degC] Focuser temperature"); } /* Rotator */ if (!string.IsNullOrEmpty(metaData.Rotator.Name)) { /* NINA */ Add("ROTNAME", metaData.Rotator.Name, "Rotator equipment name"); } if (!double.IsNaN(metaData.Rotator.MechanicalPosition)) { /* fits4win */ Add("ROTATOR", metaData.Rotator.MechanicalPosition, "[deg] Mechanical rotator angle"); /* MaximDL, several observatories */ Add("ROTATANG", metaData.Rotator.MechanicalPosition, "[deg] Mechanical rotator angle"); } if (!double.IsNaN(metaData.Rotator.StepSize)) { /* NINA */ Add("ROTSTPSZ", metaData.Rotator.StepSize, "[deg] Rotator step size"); } /* Weather Data */ if (!double.IsNaN(metaData.WeatherData.CloudCover)) { Add("CLOUDCVR", metaData.WeatherData.CloudCover, "[percent] Cloud cover"); } if (!double.IsNaN(metaData.WeatherData.DewPoint)) { Add("DEWPOINT", metaData.WeatherData.DewPoint, "[degC] Dew point"); } if (!double.IsNaN(metaData.WeatherData.Humidity)) { Add("HUMIDITY", metaData.WeatherData.Humidity, "[percent] Relative humidity"); } if (!double.IsNaN(metaData.WeatherData.Pressure)) { Add("PRESSURE", metaData.WeatherData.Pressure, "[hPa] Air pressure"); } if (!double.IsNaN(metaData.WeatherData.SkyBrightness)) { Add("SKYBRGHT", metaData.WeatherData.SkyBrightness, "[lux] Sky brightness"); } if (!double.IsNaN(metaData.WeatherData.SkyQuality)) { /* fits4win */ Add("MPSAS", metaData.WeatherData.SkyQuality, "[mags/arcsec^2] Sky quality"); } if (!double.IsNaN(metaData.WeatherData.SkyTemperature)) { Add("SKYTEMP", metaData.WeatherData.SkyTemperature, "[degC] Sky temperature"); } if (!double.IsNaN(metaData.WeatherData.StarFWHM)) { Add("STARFWHM", metaData.WeatherData.StarFWHM, "Star FWHM"); } if (!double.IsNaN(metaData.WeatherData.Temperature)) { Add("AMBTEMP", metaData.WeatherData.Temperature, "[degC] Ambient air temperature"); } if (!double.IsNaN(metaData.WeatherData.WindDirection)) { Add("WINDDIR", metaData.WeatherData.WindDirection, "[deg] Wind direction: 0=N, 180=S, 90=E, 270=W"); } if (!double.IsNaN(metaData.WeatherData.WindGust)) { Add("WINDGUST", metaData.WeatherData.WindGust * 3.6, "[kph] Wind gust"); } if (!double.IsNaN(metaData.WeatherData.WindSpeed)) { Add("WINDSPD", metaData.WeatherData.WindSpeed * 3.6, "[kph] Wind speed"); } //ROWORDER as proposed by Siril at https://free-astro.org/index.php?title=Siril:FITS_orientation Add("ROWORDER", "TOP-DOWN", "FITS Image Orientation"); Add("EQUINOX", 2000.0d, "Equinox of celestial coordinate system"); Add("SWCREATE", string.Format("N.I.N.A. {0} ({1})", Utility.Version, DllLoader.IsX86() ? "x86" : "x64"), "Software that created this file"); }
public void FITSDefaultMetaDataPopulated() { //Arrange var metaData = new ImageMetaData(); var expectedHeaderCards = new List <FITSHeaderCard>() { new FITSHeaderCard("XBINNING", 1, "X axis binning factor"), new FITSHeaderCard("YBINNING", 1, "Y axis binning factor"), new FITSHeaderCard("ROWORDER", "TOP-DOWN", "FITS Image Orientation"), new FITSHeaderCard("EQUINOX", 2000d, "Equinox of celestial coordinate system"), new FITSHeaderCard("SWCREATE", string.Format("N.I.N.A. {0} ({1})", Utility.Version, DllLoader.IsX86() ? "x86" : "x64"), "Software that created this file"), }; //Act var sut = new FITS(new ushort[] { 1, 2 }, 1, 1); sut.PopulateHeaderCards(metaData); //Assert sut.Header.HeaderCards.Count.Should().Be(expectedHeaderCards.Count + 7); // 7 is the default header size foreach (var expectedCard in expectedHeaderCards) { sut.Header.HeaderCards.First(x => x.Key == expectedCard.Key).Should().BeEquivalentTo(expectedCard); } }