Esempio n. 1
0
        public static bool IsAvailable(AstroImage image)
        {
            if (image != null && image.Pixelmap != null && image.Pixelmap.Pixels != null &&
                image.Pixelmap.Pixels.Length > 45)
            {
                try
                {
                    var data      = image.Pixelmap.Pixels.Take(45).Select(x => (byte)x).ToArray();
                    var hdr       = new QHYImageHeader(data);
                    var startTime = hdr.StartTime;
                    var endTime   = hdr.EndTime;
                    var lng       = hdr.ParseLongitude;
                    var lat       = hdr.ParseLatitude;
                    return(hdr.MaxClock >= 9999000 &&
                           hdr.MaxClock <= 10000500 &&
                           endTime > startTime &&
                           (endTime - startTime).TotalMinutes < 60 &&
                           endTime.Year > 2015 && endTime.Year < 2100 &&
                           lng >= -360 && lng <= 360 &&
                           lat >= -90 && lat <= 90);
                }
                catch (Exception ex)
                {
                    Trace.WriteLine(ex.ToString());
                }
            }

            return(false);
        }
Esempio n. 2
0
        private void timer1_Tick(object sender, EventArgs e)
        {
            timer1.Enabled = false;

            StarMapInternalConfig starMapConfig = StarMapInternalConfig.Default;

            if (rbAuto.Checked)
            {
                starMapConfig.OptimumStarsInField = (int)TangraConfig.Settings.Astrometry.PyramidOptimumStarsToMatch;
                starMapConfig.StarMapperTolerance = 2;
            }
            else
            {
                starMapConfig.OptimumStarsInField = -1;
                starMapConfig.StarMapperTolerance = trbarDepth.Value;
            }

            var starMap = new StarMap();

            var image = new AstroImage(m_InitialPixelmap);

            starMap.FindBestMap(
                starMapConfig,
                image,
                AstrometryContext.Current.OSDRectToExclude,
                AstrometryContext.Current.RectToInclude,
                AstrometryContext.Current.LimitByInclusion);

            AstrometryContext.Current.StarMap       = starMap;
            AstrometryContext.Current.StarMapConfig = starMapConfig;

            m_VideoController.RedrawCurrentFrame(false, true, false);
        }
Esempio n. 3
0
 public SpectraReader(AstroImage image, float angleDegrees, float pixelValueCoefficient)
 {
     m_Image            = image;
     m_Mapper           = new RotationMapper(image.Width, image.Height, angleDegrees);
     m_SourceVideoFrame = new RectangleF(0, 0, image.Width, image.Height);
     m_PixelValueCoeff  = pixelValueCoefficient;
 }
Esempio n. 4
0
        public frmDefineDynamicRange(VideoController videoController)
        {
            InitializeComponent();

            m_VideoController = videoController;

            m_MaxPixelValue = m_VideoController.EffectiveMaxPixelValue;
            m_Bpp           = m_VideoController.VideoBitPix;

            tbarFrom.Minimum       = 0;
            tbarFrom.Maximum       = (int)m_MaxPixelValue;
            tbarFrom.Value         = (int)Math.Min(m_MaxPixelValue, Math.Max(0, m_VideoController.DynamicFromValue));
            tbarFrom.TickFrequency = (int)Math.Ceiling(tbarFrom.Maximum / 256.0);
            tbarFrom.SmallChange   = tbarFrom.TickFrequency;
            tbarFrom.LargeChange   = tbarFrom.TickFrequency;
            tbarTo.Minimum         = 0;
            tbarTo.Maximum         = (int)m_MaxPixelValue;
            tbarTo.Value           = (int)Math.Min(m_MaxPixelValue, Math.Max(0, m_VideoController.DynamicToValue));
            tbarTo.TickFrequency   = (int)Math.Ceiling(tbarTo.Maximum / 256.0);
            tbarTo.SmallChange     = tbarFrom.TickFrequency;
            tbarTo.LargeChange     = tbarFrom.TickFrequency;

            AstroImage image = m_VideoController.GetCurrentAstroImage(false);

            if (image != null)
            {
                PopulateDistribution(image.Pixelmap.Pixels);
            }

            PlotData();
            DrawHistogram();
        }
Esempio n. 5
0
        public void ShowImageHeader(AstroImage currentImage)
        {
            try
            {
                var hdr = new QHYImageHeader(currentImage);

                lblSeqNo.Text  = hdr.SeqNumber.ToString();
                lblTempNo.Text = hdr.TempNumber.ToString();

                lblGpsState.Text = hdr.GPSStatus.ToString();
                lblMaxClock.Text = hdr.MaxClock.ToString();
                try
                {
                    lblStartTime.Text = hdr.StartTime.ToString("yyyy-MM-dd  HH:mm:ss.fffffff");
                    lblEndTime.Text   = hdr.EndTime.ToString("yyyy-MM-dd  HH:mm:ss.fffffff");
                }
                catch { }

                lblStartFlag.Text = "0x" + Convert.ToString(hdr.StartFlag, 16).PadLeft(2, '0');
                lblEndFlag.Text   = "0x" + Convert.ToString(hdr.EndFlag, 16).PadLeft(2, '0');
                lblNowFlag.Text   = "0x" + Convert.ToString(hdr.NowFlag, 16).PadLeft(2, '0');

                lblLongitude.Text = AstroConvert.ToStringValue(hdr.ParseLongitude, "+DD°MM'SS.TT\"");
                lblLatitude.Text  = AstroConvert.ToStringValue(hdr.ParseLatitude, "+DD°MM'SS.TT\"");
                lblImageSize.Text = string.Format("{0} x {1}", hdr.Width, hdr.Height);
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex);
            }
        }
Esempio n. 6
0
        public static Dictionary <ImagePixel, double> LocateHotPixels(AstroImage image, int averageNTopCandidates)
        {
            var rv = LocateHotPixels(image, s_OriginalSample, s_OriginalSampleMedian);

            if (averageNTopCandidates > 0)
            {
                var allCenters = averageNTopCandidates < s_Candidates.Length
                    ? s_Candidates.Take(averageNTopCandidates)
                    : s_Candidates;

                // Horrible hack !!!
                s_CombinedSample     = new uint[7, 7];
                s_NumSamplesCombined = 1;

                foreach (var pixel in allCenters)
                {
                    var model = image.GetPixelsArea(pixel.X, pixel.Y, 7);
                    RegisterHotPixelSample(model, image.Pixelmap.MaxSignalValue);
                }

                rv = LocateHotPixels(image, s_CombinedSample, s_CombinedSampleMedian);
            }

            return(rv);
        }
Esempio n. 7
0
            public static bool RunAtFocusAny(AstroImage asti, int aftype)
            {
                //Run @Focus2 or 3 with filternumber.  return True if (successful, false if (not

                //   Before running this method, save the current target name and camera configuration so it can be found again
                //   Restore current target, using Name with Find method, and reload camera configuration afterwards
                //   as @Focus3 using automatic star search off, overwrites the observating list and object)
                //   Also, may want to run Closed}Slew back to target and Turn on temperature compensation (A)
                //

                //Make sure focuser is connected
                //Create camera object
                ccdsoftCamera tsxc = new ccdsoftCamera
                {
                    Asynchronous        = 0,
                    AutoSaveFocusImages = 0,
                    ImageReduction      = (ccdsoftImageReduction)asti.ImageReduction,
                    Frame = (ccdsoftImageFrame)asti.Frame,
                    FilterIndexZeroBased = asti.Filter,
                    FocusExposureTime    = asti.Exposure,
                    Delay = 0
                };

                //Run @Focus2 or 3
                //   Create a camera object
                //   Launch the autofocus watching out for an exception -- which will be posted in TSX
                switch (aftype)
                {
                case 2:
                    try
                    { int focstat = tsxc.AtFocus2(); }
                    catch
                    {
                        //Just close up, TSX will spawn error window unless this is an abort
                        //lg.LogIt("@Focus2 fails for " + ex.Message);
                        return(false);
                    }
                    //@Focus2 will generate an observing list.  Clear it.
                    break;

                case 3:
                    try
                    { int focstat = tsxc.AtFocus3(3, true); }
                    catch
                    {
                        //Just close up, TSX will spawn error window unless this is an abort
                        //lg.LogIt("@Focus3 fails for " + ex.Message);
                        return(false);
                    }
                    //lg.LogIt("@Focus3 successful");
                    break;

                default:
                    // lg.LogIt("Unknown AtFocus selection -- focus failed");
                    break;
                }
                return(true);
            }
Esempio n. 8
0
        public frmObjectResolver(
			AstroImage img, 
			Dictionary<PSFFit, IStar> mappedObjects, 
			Dictionary<PSFFit, double> unknownObjects)
        {
            InitializeComponent();

            m_Image = img;
            m_MappedObjects = mappedObjects;
            m_UnknownObjects = unknownObjects;
        }
Esempio n. 9
0
        public frmObjectResolver(
            AstroImage img,
            Dictionary <PSFFit, IStar> mappedObjects,
            Dictionary <PSFFit, double> unknownObjects)
        {
            InitializeComponent();

            m_Image          = img;
            m_MappedObjects  = mappedObjects;
            m_UnknownObjects = unknownObjects;
        }
Esempio n. 10
0
        internal frmAddOrEditMutualEventsTarget(int objectId, TrackedObjectConfig selectedObject, LCStateMachine state, VideoController videoController)
        {
            InitializeComponent();

            m_VideoController = videoController;

            Text              = "Edit 'Mutual Event' Target";
            btnAdd.Text       = "Save";
            btnDontAdd.Text   = "Cancel";
            btnDelete.Visible = true;
            m_IsEdit          = true;

            m_ObjectId   = objectId;
            m_State      = state;
            m_AstroImage = m_VideoController.GetCurrentAstroImage(false);

            ObjectToAdd = selectedObject;

            float?commonAperture = m_State.MeasuringApertures.Count > 0
                                ? m_State.MeasuringApertures[0] :
                                   (float?)null;

            m_Aperture  = commonAperture;
            m_Aperture1 = commonAperture;
            m_Aperture2 = commonAperture;

            m_Center         = new ImagePixel(selectedObject.ApertureStartingX, selectedObject.ApertureStartingY);
            m_OriginalCenter = new ImagePixel(selectedObject.ApertureStartingX, selectedObject.ApertureStartingY);

            if (selectedObject.ProcessInPsfGroup)
            {
                m_GroupId = selectedObject.GroupId;

                List <TrackedObjectConfig> otherGroupedObjects = state.m_MeasuringStars.Where(x => m_GroupId >= 0 && x.GroupId == m_GroupId && x != selectedObject).ToList();
                if (otherGroupedObjects.Count == 1)
                {
                    ObjectToAdd2 = otherGroupedObjects[0];
                    m_ObjectId2  = state.m_MeasuringStars.IndexOf(ObjectToAdd2);
                }
            }
            else
            {
                ObjectToAdd2 = null;
                m_GroupId    = objectId;
                // If we are to use a second object, it should have the next available Id
                m_ObjectId2 = state.m_MeasuringStars.Count;
            }

            m_EditingOccultedStar = selectedObject.IsOcultedStar();

            Initialise();
        }
Esempio n. 11
0
        public void PlateSolve(PlateSolveTesterConfig config)
        {
            var pixelMap = new Pixelmap(config.Width, config.Height, config.BitPix, config.Pixels, null, null);
            var image    = new AstroImage(pixelMap);

            StarMap starMap = new StarMap(
                TangraConfig.Settings.Astrometry.PyramidRemoveNonStellarObject,
                TangraConfig.Settings.Astrometry.MinReferenceStarFWHM,
                TangraConfig.Settings.Astrometry.MaxReferenceStarFWHM,
                TangraConfig.Settings.Astrometry.MaximumPSFElongation,
                TangraConfig.Settings.Astrometry.LimitReferenceStarDetection);

            Rectangle excludeRect = new Rectangle(config.OSDRectToExclude.X, config.OSDRectToExclude.Y, config.OSDRectToExclude.Width, config.OSDRectToExclude.Height);
            Rectangle includeRect = new Rectangle(config.RectToInclude.X, config.RectToInclude.Y, config.RectToInclude.Width, config.RectToInclude.Height);

            starMap.FindBestMap(
                StarMapInternalConfig.Default,
                image,
                excludeRect,
                includeRect,
                config.LimitByInclusion);

            var facade         = new StarCatalogueFacade(TangraConfig.Settings.StarCatalogue);
            var catalogueStars = facade.GetStarsInRegion(
                config.RADeg,
                config.DEDeg,
                (config.ErrFoVs + 1.0) * config.PlateConfig.GetMaxFOVInArcSec() / 3600.0,
                config.LimitMagn,
                config.Epoch);

            var distBasedMatcher = new DistanceBasedAstrometrySolver(
                new MockedOperationNotifier(),
                config.PlateConfig,
                TangraConfig.Settings.Astrometry,
                catalogueStars,
                config.RADeg,
                config.DEDeg,
                config.DetermineAutoLimitMagnitude);

            distBasedMatcher.SetMinMaxMagOfStarsForAstrometry(config.PyramidMinMag, config.LimitMagn);
            distBasedMatcher.SetMinMaxMagOfStarsForPyramidAlignment(config.PyramidMinMag, config.PyramidMaxMag);

            distBasedMatcher.InitNewMatch(starMap, PyramidMatchType.PlateSolve, null);


            distBasedMatcher.InitNewFrame(starMap);

            distBasedMatcher.SetManuallyIdentifiedHints(new Dictionary <PSFFit, IStar>());

            LeastSquareFittedAstrometry astrometricFit;
            PerformMatchResult          result = distBasedMatcher.PerformMatch(out astrometricFit);
        }
Esempio n. 12
0
        private void btnLoad_Click(object sender, EventArgs e)
        {
            if (File.Exists(tbxFileLocation.Text))
            {
                m_Frame = (Bitmap)Bitmap.FromFile(tbxFileLocation.Text);
                //m_FieldsFrame = BitmapFilter.ToVideoFields(m_Frame);

                m_Pixelmap = Pixelmap.ConstructFromBitmap(m_Frame, TangraConfig.ColourChannel.GrayScale);
                m_Image    = new AstroImage(m_Pixelmap);

                m_InitialPixels = m_Image.GetOcrPixels();

                pictureBox1.Load(tbxFileLocation.Text);
            }
        }
Esempio n. 13
0
        internal frmAddOrEditSingleTarget(int objectId, ImagePixel center, PSFFit gaussian, LCStateMachine state, VideoController videoController)
        {
            InitializeComponent();

            m_VideoController = videoController;

            m_AutocenteredApertureAvailable = true;

            Text              = "Add Object";
            btnAdd.Text       = "Add";
            btnDontAdd.Text   = "Don't Add";
            btnDelete.Visible = false;
            m_IsEdit          = false;

            nudFitMatrixSize.Value   = 11;
            nudFitMatrixSize.Maximum = 15;

            m_ObjectId   = objectId;
            m_State      = state;
            m_AstroImage = m_State.VideoOperation.m_StackedAstroImage;

            ObjectToAdd = new TrackedObjectConfig();

            m_Center = new ImagePixel(center);

            Initialize();

            if (rbOccultedStar.Enabled)
            {
                SelectedObjectType = TrackingType.OccultedStar;
            }
            else
            {
                SelectedObjectType = TrackingType.GuidingStar;
            }

            // Apply filtering to the processing pixels according to the configured default filter value
            int matirxSize = (int)nudFitMatrixSize.Value;

            GetFitInMatrix(gaussian, ref matirxSize);

            nudFitMatrixSize.Maximum = matirxSize;

            if (SelectedObjectType != TrackingType.OccultedStar)
            {
                SetHeightAndType();
            }
        }
Esempio n. 14
0
        public frmRunMultiFrameSpectroscopy(IFramePlayer framePlayer, VideoSpectroscopyOperation videoOperation, AstroImage astroImage)
            : this()
        {
            m_VideoOperation = videoOperation;
            m_AstroImage     = astroImage;

            nudNumberMeasurements.Maximum = framePlayer.Video.LastFrame - framePlayer.CurrentFrameIndex;
            nudNumberMeasurements.SetNUDValue(Math.Min(200, nudNumberMeasurements.Maximum));
            nudAreaWing.SetNUDValue(Math.Min(videoOperation.MeasurementAreaWing, nudAreaWing.Maximum));
            nudBackgroundWing.SetNUDValue(Math.Min(videoOperation.BackgroundAreaWing, nudBackgroundWing.Maximum));
            cbxBackgroundMethod.SelectedIndex = 1; /* Median */
            cbxCombineMethod.SelectedIndex    = 1; /* Median */
            nudExposureSec.SetNUDValue(astroImage.Pixelmap.FrameState.ExposureInMilliseconds / 1000.0f);

            m_Initialised = true;
        }
Esempio n. 15
0
        public PlateObjectResolver(
            IAstrometryController astrometryController,
            IVideoController videoController,
            AstroImage image,
            LeastSquareFittedAstrometry impSol,
            List <IStar> stars,
            double maxMagForAstrometry)
        {
            m_AstrometryController = astrometryController;
            m_VideoController      = videoController;

            m_Image               = image;
            m_Astrometry          = impSol;
            m_Stars               = stars;
            m_MaxMagForAstrometry = maxMagForAstrometry;
        }
Esempio n. 16
0
        private static Bitmap GetPreviewImage(Pixelmap currFrame)
        {
            CurrFrame = new AstroImage(currFrame);
            Bitmap image = currFrame.CreateDisplayBitmapDoNotDispose();

            if (OnDrawOverlays != null)
            {
                using (Graphics g = Graphics.FromImage(image))
                {
                    OnDrawOverlays.Invoke(g);
                    g.Save();
                }
            }

            return(image);
        }
Esempio n. 17
0
        internal void ProcessFrame(int frameNo, AstroImage astroImage, DateTime timeStamp, float exposureSeconds)
        {
            string fileName = Path.GetFullPath(string.Format("{0}\\{1}_{2}.fits", m_FolderName, frameNo.ToString().PadLeft(5, '0'), timeStamp.ToString("yyyy-MMM-dd_HHmmss_fff")));

            if (m_IsFitsSequence &&
                astroImage.Pixelmap.FrameState.Tag != null &&
                astroImage.Pixelmap.FrameState.Tag is BasicHDU)
            {
                ProcessFitsFrame(fileName, astroImage.Pixelmap.FrameState.Tag as BasicHDU);
            }
            else
            {
                uint[] pixels = astroImage.Pixelmap.UnprocessedPixels ?? astroImage.Pixelmap.Pixels;
                ProcessFrame(frameNo, fileName, pixels, timeStamp, exposureSeconds);
            }
        }
Esempio n. 18
0
        protected void InitStarMap()
        {
            var starMap = new StarMap();

            AstroImage image = m_VideoController.GetCurrentAstroImage(false);

            starMap.FindBestMap(
                AstrometryContext.Current.StarMapConfig,
                image,
                AstrometryContext.Current.OSDRectToExclude,
                AstrometryContext.Current.RectToInclude,
                AstrometryContext.Current.LimitByInclusion);

            AstrometryContext.Current.StarMap = starMap;

#if ASTROMETRY_DEBUG
            Trace.Assert(AstrometryContext.Current.StarMap != null);
            Trace.Assert(AstrometryContext.Current.StarMap.Features.Count > 0);
#endif
        }
Esempio n. 19
0
        public static Dictionary <ImagePixel, double> LocateHotPixels(AstroImage image, uint[,] model, uint modelMedian)
        {
            var rv = new Dictionary <ImagePixel, double>();

            if (s_NumSamplesCombined > 0)
            {
                int  width        = image.Pixelmap.Width;
                int  height       = image.Pixelmap.Height;
                uint abv          = model[3, 3] - modelMedian;
                uint minPeakLevel = (uint)(modelMedian + PEAK_PIXEL_LEVEL_REQUIRED * abv);
                EnumeratePeakPixels(image.Pixelmap.GetPixelsCopy(), width, height, minPeakLevel, Rectangle.Empty,
                                    (x, y, z) =>
                {
                    if (x >= 3 && x < width - 3 && y >= 3 && y < height - 3)
                    {
                        var newPix = new ImagePixel((int)z, x, y);
                        if (!rv.Keys.ToArray().Any(p => p.DistanceTo(newPix) < 5))
                        {
                            rv.Add(newPix, long.MinValue);
                        }
                    }
                });

                foreach (ImagePixel center in rv.Keys.ToArray())
                {
                    uint[,] testArea = image.GetPixelsArea(center.X, center.Y, 7);
                    var score = ScoreArea(testArea);
                    rv[center] = score.Item1;
                }

                var positions = rv.Keys.ToArray();
                var scores    = rv.Values.ToArray();
                Array.Sort(scores, positions);
                s_Candidates      = positions;
                s_CandidateScores = scores;
            }

            return(rv);
        }
Esempio n. 20
0
        internal frmAddOrEditMutualEventsTarget(int objectId, ImagePixel center, PSFFit gaussian, LCStateMachine state, VideoController videoController, bool tryAutoDoubleFind)
        {
            InitializeComponent();

            m_VideoController   = videoController;
            m_TryAutoDoubleFind = tryAutoDoubleFind;

            Text              = "Add 'Mutual Event' Target";
            btnAdd.Text       = "Add";
            btnDontAdd.Text   = "Don't Add";
            btnDelete.Visible = false;
            m_IsEdit          = false;

            m_ObjectId   = objectId;
            m_GroupId    = objectId;          // For Group Id we use the next object id
            m_State      = state;
            m_AstroImage = m_VideoController.GetCurrentAstroImage(false);

            ObjectToAdd  = null;
            ObjectToAdd2 = null;

            float?commonAperture = m_State.MeasuringApertures.Count > 0
                                ? m_State.MeasuringApertures[0] :
                                   (float?)null;

            m_Aperture  = commonAperture;
            m_Aperture1 = commonAperture;
            m_Aperture2 = commonAperture;

            m_Center         = new ImagePixel(center);
            m_OriginalCenter = new ImagePixel(center);

            m_EditingOccultedStar = false;

            Initialise();
        }
Esempio n. 21
0
        public static StarMagnitudeFit PerformFit(
            IAstrometryController astrometryController,
            IVideoController videoController,
            int bitPix,
            uint maxSignalValue,
            FitInfo astrometricFit,
            TangraConfig.PhotometryReductionMethod photometryReductionMethod,
            TangraConfig.PsfQuadrature psfQuadrature,
            TangraConfig.PsfFittingMethod psfFittingMethod,
            TangraConfig.BackgroundMethod photometryBackgroundMethod,
            TangraConfig.PreProcessingFilter filter,
            List <IStar> catalogueStars,
            Guid magnitudeBandId,
            float encodingGamma,
            TangraConfig.KnownCameraResponse reverseCameraResponse,
            float?aperture,
            float?annulusInnerRadius,
            int?annulusMinPixels,
            ref float empericalPSFR0)
        {
            uint saturatedValue = TangraConfig.Settings.Photometry.Saturation.GetSaturationForBpp(bitPix, maxSignalValue);

            MeasurementsHelper measurer = new MeasurementsHelper(
                bitPix,
                photometryBackgroundMethod,
                TangraConfig.Settings.Photometry.SubPixelSquareSize,
                saturatedValue);

            measurer.SetCoreProperties(
                annulusInnerRadius ?? TangraConfig.Settings.Photometry.AnnulusInnerRadius,
                annulusMinPixels ?? TangraConfig.Settings.Photometry.AnnulusMinPixels,
                CorePhotometrySettings.Default.RejectionBackgroundPixelsStdDev,
                2 /* TODO: This must be configurable */);

            var bgProvider = new BackgroundProvider(videoController);

            measurer.GetImagePixelsCallback += new MeasurementsHelper.GetImagePixelsDelegate(bgProvider.measurer_GetImagePixelsCallback);

            List <double> intencities    = new List <double>();
            List <double> magnitudes     = new List <double>();
            List <double> colours        = new List <double>();
            List <double> residuals      = new List <double>();
            List <bool>   saturatedFlags = new List <bool>();
            List <IStar>  stars          = new List <IStar>();
            List <PSFFit> gaussians      = new List <PSFFit>();

            List <MagFitRecord> fitRecords = new List <MagFitRecord>();

            AstroImage currentAstroImage = videoController.GetCurrentAstroImage(false);
            Rectangle  osdRectToExclude  = astrometryController.OSDRectToExclude;
            Rectangle  rectToInclude     = astrometryController.RectToInclude;
            bool       limitByInclusion  = astrometryController.LimitByInclusion;

            int matSize = CorePhotometrySettings.Default.MatrixSizeForCalibratedPhotometry;

            double a             = double.NaN;
            double b             = double.NaN;
            double c             = double.NaN;
            int    excludedStars = 0;
            double empericalFWHM = double.NaN;

            try
            {
                foreach (PlateConstStarPair pair in astrometricFit.AllStarPairs)
                {
                    if (limitByInclusion && !rectToInclude.Contains((int)pair.x, (int)pair.y))
                    {
                        continue;
                    }
                    if (!limitByInclusion && osdRectToExclude.Contains((int)pair.x, (int)pair.y))
                    {
                        continue;
                    }

                    IStar star = catalogueStars.Find(s => s.StarNo == pair.StarNo);
                    if (star == null || double.IsNaN(star.Mag) || star.Mag == 0)
                    {
                        continue;
                    }

                    uint[,] data = currentAstroImage.GetMeasurableAreaPixels((int)pair.x, (int)pair.y, matSize);

                    PSFFit fit = new PSFFit((int)pair.x, (int)pair.y);
                    fit.Fit(data, PSF_FIT_AREA_SIZE);
                    if (!fit.IsSolved)
                    {
                        continue;
                    }

                    MagFitRecord record = new MagFitRecord();
                    record.Star       = star;
                    record.Pair       = pair;
                    record.PsfFit     = fit;
                    record.Saturation = IsSaturated(data, matSize, saturatedValue);

                    if (!EXCLUDE_SATURATED_STARS || !record.Saturation)
                    {
                        fitRecords.Add(record);
                    }
                }

                // We need the average R0 if it hasn't been determined yet
                if (float.IsNaN(empericalPSFR0))
                {
                    empericalPSFR0 = 0;
                    foreach (MagFitRecord rec in fitRecords)
                    {
                        empericalPSFR0 += (float)rec.PsfFit.R0;
                    }
                    empericalPSFR0 /= fitRecords.Count;
                }

                empericalFWHM = 2 * Math.Sqrt(Math.Log(2)) * empericalPSFR0;

                foreach (MagFitRecord record in fitRecords)
                {
                    ImagePixel center   = new ImagePixel(255, record.Pair.x, record.Pair.y);
                    int        areaSize = filter == TangraConfig.PreProcessingFilter.NoFilter ? 17 : 19;

                    int centerX = (int)Math.Round(center.XDouble);
                    int centerY = (int)Math.Round(center.YDouble);

                    uint[,] data             = currentAstroImage.GetMeasurableAreaPixels(centerX, centerY, areaSize);
                    uint[,] backgroundPixels = currentAstroImage.GetMeasurableAreaPixels(centerX, centerY, 35);

                    measurer.MeasureObject(
                        center,
                        data,
                        backgroundPixels,
                        currentAstroImage.Pixelmap.BitPixCamera,
                        filter,
                        photometryReductionMethod,
                        psfQuadrature,
                        psfFittingMethod,
                        aperture != null ? aperture.Value : (float)Aperture(record.PsfFit.FWHM),
                        record.PsfFit.FWHM,
                        (float)empericalFWHM,
                        new FakeIMeasuredObject(record.PsfFit),
                        null,
                        null,
                        false);

                    double intensity = measurer.TotalReading - measurer.TotalBackground;
                    if (intensity > 0)
                    {
                        var mag = record.Star.GetMagnitudeForBand(magnitudeBandId);
                        var clr = record.Star.MagJ - record.Star.MagK;

                        if (!double.IsNaN(mag) && !double.IsNaN(clr) && !double.IsInfinity(mag) && !double.IsInfinity(clr))
                        {
                            intencities.Add(intensity);
                            magnitudes.Add(record.Star.GetMagnitudeForBand(magnitudeBandId));
                            colours.Add(record.Star.MagJ - record.Star.MagK);

                            gaussians.Add(record.PsfFit);
                            stars.Add(record.Star);
                            saturatedFlags.Add(measurer.HasSaturatedPixels || record.PsfFit.IMax >= measurer.SaturationValue);
                        }
                    }
                }


                // Remove stars with unusual PSF fit radii (once only)
                double sum = 0;
                for (int i = 0; i < gaussians.Count; i++)
                {
                    sum += gaussians[i].R0;
                }
                double averageR = sum / gaussians.Count;

                residuals.Clear();
                sum = 0;
                for (int i = 0; i < gaussians.Count; i++)
                {
                    residuals.Add(averageR - gaussians[i].R0);
                    sum += (averageR - gaussians[i].R0) * (averageR - gaussians[i].R0);
                }
                double stdDev = Math.Sqrt(sum) / gaussians.Count;

                if (EXCLUDE_BAD_RESIDUALS)
                {
                    for (int i = residuals.Count - 1; i >= 0; i--)
                    {
                        if (Math.Abs(residuals[i]) > 6 * stdDev)
                        {
                            intencities.RemoveAt(i);
                            magnitudes.RemoveAt(i);
                            colours.RemoveAt(i);
                            stars.RemoveAt(i);
                            gaussians.RemoveAt(i);
                            saturatedFlags.RemoveAt(i);
                        }
                    }
                }

                double maxResidual = Math.Max(0.1, TangraConfig.Settings.Photometry.MaxResidualStellarMags);

                for (int itter = 1; itter <= MAX_ITERR; itter++)
                {
                    residuals.Clear();

                    SafeMatrix A = new SafeMatrix(intencities.Count, 3);
                    SafeMatrix X = new SafeMatrix(intencities.Count, 1);

                    int idx = 0;
                    for (int i = 0; i < intencities.Count; i++)
                    {
                        A[idx, 0] = magnitudes[i];
                        A[idx, 1] = colours[i];
                        A[idx, 2] = 1;

                        X[idx, 0] = -2.5 * Math.Log10(intencities[i]);

                        idx++;
                    }

                    SafeMatrix a_T    = A.Transpose();
                    SafeMatrix aa     = a_T * A;
                    SafeMatrix aa_inv = aa.Inverse();
                    SafeMatrix bx     = (aa_inv * a_T) * X;

                    double Ka = bx[0, 0];
                    double Kb = bx[1, 0];
                    double Kc = bx[2, 0];

                    // -2.5 * a * Log(Median-Intensity) = A * Mv + B * Mjk + C - b
                    // -2.5 * Log(Median-Intensity) = Ka * Mv + Kb * Mjk + Kc
                    // Mv = -2.5 * a * Log(Median-Intensity) - b * Mjk - c
                    a = 1 / Ka;
                    b = -Kb / Ka;
                    c = -Kc / Ka;

                    int starsExcludedThisTime = 0;

                    if (EXCLUDE_BAD_RESIDUALS)
                    {
                        List <int> indexesToRemove = new List <int>();
                        for (int i = 0; i < intencities.Count; i++)
                        {
                            double computed = a * -2.5 * Math.Log10(intencities[i]) + b * colours[i] + c;

                            double diff = Math.Abs(computed - magnitudes[i]);
                            if (itter < MAX_ITERR)
                            {
                                if (Math.Abs(diff) > maxResidual)
                                {
                                    indexesToRemove.Add(i);
                                }
                            }
                            else
                            {
                                residuals.Add(diff);
                            }
                        }


                        for (int i = indexesToRemove.Count - 1; i >= 0; i--)
                        {
                            int idxToRemove = indexesToRemove[i];
                            intencities.RemoveAt(idxToRemove);
                            magnitudes.RemoveAt(idxToRemove);
                            colours.RemoveAt(idxToRemove);
                            stars.RemoveAt(idxToRemove);
                            gaussians.RemoveAt(idxToRemove);
                            saturatedFlags.RemoveAt(idxToRemove);

                            excludedStars++;
                            starsExcludedThisTime++;
                        }
                    }

                    if (starsExcludedThisTime == 0)
                    {
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.ToString());
            }

            return(new StarMagnitudeFit(
                       currentAstroImage,
                       bitPix,
                       intencities, magnitudes, colours, stars, gaussians, new List <double>(),
                       saturatedFlags, a, b, c, encodingGamma, reverseCameraResponse, excludedStars, filter, empericalFWHM,
                       photometryReductionMethod, photometryBackgroundMethod, psfQuadrature, psfFittingMethod, measurer, aperture));
        }
Esempio n. 22
0
        public void NextFrame(int frameNo, MovementType movementType, bool isLastFrame, AstroImage astroImage, int firstFrameInIntegrationPeriod, string frameFileName)
        {
            m_CurrentAstroImage = astroImage;
            m_FrameNumber       = frameNo;
            TangraContext.Current.CrashReportInfo.FrameNumber = frameNo;

            if (m_Running)
            {
                if (m_FramesDone < m_NumFrames)
                {
                    Pixelmap currPixelmap = astroImage.Pixelmap;
                    if (m_FramesDone == 0)
                    {
                        m_AveragedData = new float[currPixelmap.Width, currPixelmap.Height];
                    }

                    for (int x = 0; x < currPixelmap.Width; x++)
                    {
                        for (int y = 0; y < currPixelmap.Height; y++)
                        {
                            m_AveragedData[x, y] += currPixelmap[x, y];
                        }
                    }

                    m_FramesDone++;
                    m_ControlPanel.SetProgress(m_FramesDone);

                    if (m_FramesDone == m_NumFrames)
                    {
                        // Averaging
                        for (int x = 0; x < currPixelmap.Width; x++)
                        {
                            for (int y = 0; y < currPixelmap.Height; y++)
                            {
                                m_AveragedData[x, y] = (m_AveragedData[x, y] / (ulong)m_FramesDone);
                            }
                        }

                        m_ControlPanel.SetStopped();

                        string fileName = string.Format("{0}_{1}.fit", Path.GetFileNameWithoutExtension(m_VideoController.CurrentVideoFileName), m_FrameType.ToString());

                        if (m_VideoController.ShowSaveFileDialog(
                                "Save " + m_FrameType.ToString() + " fame",
                                "FITS Image (*.fit)|*.fit",
                                ref fileName) == DialogResult.OK)
                        {
                            string notes = string.Format("{0} generated from {1}", m_FrameType.ToString(), Path.GetFileNameWithoutExtension(m_VideoController.CurrentVideoFileName));

                            SaveDarkOrFlatFrame(fileName, currPixelmap.Width, currPixelmap.Height, notes, m_AveragedData, m_ExposureSeconds, m_NumFrames);
                        }

                        m_Running = false;
                        m_VideoController.StopVideo();

                        if (m_FrameType == FrameType.Dark)
                        {
                            UsageStats.Instance.DarkFramesProduced++;
                        }
                        if (m_FrameType == FrameType.MasterFlat)
                        {
                            UsageStats.Instance.FlatFramesProduced++;
                        }

                        UsageStats.Instance.Save();
                    }
                }
            }
        }
Esempio n. 23
0
        internal frmAddOrEditSingleTarget(int objectId, TrackedObjectConfig selectedObject, LCStateMachine state, VideoController videoController)
        {
            InitializeComponent();

            m_VideoController = videoController;

            m_AutocenteredApertureAvailable = true;

            Text = "Edit Object";

            btnAdd.Text       = "Save";
            btnDontAdd.Text   = "Cancel";
            btnDelete.Visible = true;
            m_IsEdit          = true;

            m_ObjectId   = objectId;
            m_State      = state;
            m_AstroImage = m_State.VideoOperation.m_StackedAstroImage;

            ObjectToAdd = selectedObject;

            if (selectedObject.TrackingType != TrackingType.ComparisonStar)
            {
                nudFitMatrixSize.SetNUDValue(selectedObject.PsfFitMatrixSize);
            }

            m_Center = new ImagePixel(
                selectedObject.OriginalFieldCenterX,
                selectedObject.OriginalFieldCenterY);

            if (ObjectToAdd.PositionTolerance > 0)
            {
                nudPositionTolerance.SetNUDValue((decimal)ObjectToAdd.PositionTolerance);
            }

            Initialize();

            if (!selectedObject.IsWeakSignalObject && !selectedObject.IsFixedAperture)
            {
                int matrixSize = selectedObject.PsfFitMatrixSize;
                GetFitInMatrix(selectedObject.Gaussian, ref matrixSize, selectedObject.ApertureInPixels);
                selectedObject.PsfFitMatrixSize = matrixSize;
            }
            else
            {
                m_ProcessingPixels = m_AstroImage.GetMeasurableAreaPixels(m_Center);
                m_DisplayPixels    = m_AstroImage.GetMeasurableAreaDisplayBitmapPixels(m_Center);

                m_FWHM     = 6;
                m_Gaussian = null;
                m_X0       = selectedObject.ApertureMatrixX0;
                m_Y0       = selectedObject.ApertureMatrixY0;
                dx         = selectedObject.ApertureDX;
                dy         = selectedObject.ApertureDY;

                PlotSingleTargetPixels();

                nudAperture1.SetNUDValue((decimal)Math.Round(ObjectToAdd.ApertureInPixels, 2));
            }

            SetHeightAndType();

            if (selectedObject.TrackingType == TrackingType.GuidingStar)
            {
                SelectedObjectType = TrackingType.GuidingStar;
            }
            else if (selectedObject.TrackingType == TrackingType.OccultedStar)
            {
                SelectedObjectType = TrackingType.OccultedStar;
            }
        }
Esempio n. 24
0
 internal PeakPixelResolver(AstroImage image)
 {
     m_Image = image;
 }
Esempio n. 25
0
        public static void PSFPhotometry(FitInfo astrometricFit, List <IStar> catalogueStars, AstroImage currentAstroImage, Rectangle osdRectToExclude, Rectangle rectToInclude, bool limitByInclusion)
        {
            StringBuilder output = new StringBuilder();

            foreach (PlateConstStarPair pair in astrometricFit.AllStarPairs)
            {
                uint[,] data = currentAstroImage.GetMeasurableAreaPixels(
                    (int)Math.Round(pair.x), (int)Math.Round(pair.y), 9);

                if (limitByInclusion && !rectToInclude.Contains((int)pair.x, (int)pair.y))
                {
                    continue;
                }
                if (!limitByInclusion && osdRectToExclude.Contains((int)pair.x, (int)pair.y))
                {
                    continue;
                }

                PSFFit gaussian = new PSFFit((int)Math.Round(pair.x), (int)Math.Round(pair.y));
                gaussian.Fit(data);
                if (gaussian.IsSolved)
                {
                    IStar star = catalogueStars.Find(s => s.StarNo == pair.StarNo);
                    if (star != null &&
                        !double.IsNaN(star.MagR))
                    {
                        output.AppendLine(string.Format("{0}, {1}, {2}, {3}, {4}", pair.StarNo, star.MagR, gaussian.R0, gaussian.IMax, gaussian.I0));
                    }
                }
            }

            File.WriteAllText(@"C:\PSF_Photo.csv", output.ToString());
        }
Esempio n. 26
0
 public QHYImageHeader(AstroImage image)
     : this(image.Pixelmap.Pixels.Take(45).Select(x => (byte)x).ToArray())
 {
 }
Esempio n. 27
0
        private void InitStarAmplitudeModelling(ModelConfig modelConfig, float accuracy, int bitPix, uint maxSignalValue)
        {
            if (m_MagnitudeToPeakDict != null)
            {
                return;
            }

            m_MagnitudeToPeakDict  = new Dictionary <double, int>();
            m_MagnitudeToPeakMags  = new List <double>();
            m_MagnitudeToPeakPeaks = new List <int>();

            var mea = new MeasurementsHelper(
                bitPix,
                TangraConfig.BackgroundMethod.BackgroundMedian,
                TangraConfig.Settings.Photometry.SubPixelSquareSize,
                TangraConfig.Settings.Photometry.Saturation.GetSaturationForBpp(bitPix, maxSignalValue));

            float apertureSize       = APERTURE;
            float annulusInnerRadius = (GAP + APERTURE) / APERTURE;
            int   annulusMinPixels   = (int)(Math.PI * (Math.Pow(ANNULUS + GAP + APERTURE, 2) - Math.Pow(GAP + APERTURE, 2)));

            mea.SetCoreProperties(annulusInnerRadius, annulusMinPixels, CorePhotometrySettings.Default.RejectionBackgroundPixelsStdDev, 2 /* TODO: This must be configurable */);

            int    peak        = (int)(maxSignalValue - (modelConfig.NoiseMean + modelConfig.DarkFrameMean) * modelConfig.Integration);
            int    TOTAL_STEPS = 100;
            double step        = Math.Log10(peak) / TOTAL_STEPS;
            double zeroMag     = double.NaN;

            for (int ii = 0; ii < TOTAL_STEPS; ii++)
            {
                int      amplitude = (int)Math.Round(Math.Pow(10, Math.Log10(peak) - ii * step));
                Pixelmap pixmap    = new Pixelmap(64, 64, bitPix, new uint[64 * 64], null, null);
                VideoModelUtils.GenerateStar(pixmap, 32, 32, (float)modelConfig.FWHM, amplitude, 0 /* Gaussian */);
                PSFFit     fit = new PSFFit(32, 32);
                AstroImage img = new AstroImage(pixmap);
                uint[,] data             = img.GetMeasurableAreaPixels(32, 32, 17);
                uint[,] backgroundPixels = img.GetMeasurableAreaPixels(32, 32, 35);

                fit.Fit(data);

                var result = mea.MeasureObject(new ImagePixel(32, 32), data, backgroundPixels, pixmap.BitPixCamera,
                                               TangraConfig.PreProcessingFilter.NoFilter,
                                               TangraConfig.PhotometryReductionMethod.AperturePhotometry, TangraConfig.PsfQuadrature.NumericalInAperture,
                                               TangraConfig.PsfFittingMethod.DirectNonLinearFit,
                                               apertureSize, modelConfig.FWHM, (float)modelConfig.FWHM,
                                               new FakeIMeasuredObject(fit),
                                               null, null,
                                               false);

                if (result == NotMeasuredReasons.TrackedSuccessfully && !mea.HasSaturatedPixels)
                {
                    // Add value for fitting
                    double measurement = mea.TotalReading - mea.TotalBackground;
                    if (double.IsNaN(zeroMag))
                    {
                        zeroMag = modelConfig.BrighestUnsaturatedStarMag + 2.5 * Math.Log10(measurement);
                    }
                    double magnitude = -2.5 * Math.Log10(measurement) + zeroMag;

                    m_MagnitudeToPeakDict[magnitude] = amplitude;
                    m_MagnitudeToPeakMags.Add(magnitude);
                    m_MagnitudeToPeakPeaks.Add(amplitude);
                }
            }
        }
Esempio n. 28
0
        private void GenerateFrame(Pixelmap pixmap, List <IStar> stars, ModelConfig modelConfig)
        {
            var mea = new MeasurementsHelper(
                pixmap.BitPixCamera,
                TangraConfig.BackgroundMethod.BackgroundMedian,
                TangraConfig.Settings.Photometry.SubPixelSquareSize,
                TangraConfig.Settings.Photometry.Saturation.GetSaturationForBpp(pixmap.BitPixCamera, pixmap.MaxSignalValue));

            float apertureSize       = APERTURE;
            float annulusInnerRadius = (GAP + APERTURE) / APERTURE;
            int   annulusMinPixels   = (int)(Math.PI * (Math.Pow(ANNULUS + GAP + APERTURE, 2) - Math.Pow(GAP + APERTURE, 2)));

            mea.SetCoreProperties(annulusInnerRadius, annulusMinPixels, CorePhotometrySettings.Default.RejectionBackgroundPixelsStdDev, 2 /* TODO: This must be configurable */);

            var measurements = new Dictionary <IStar, double>();

            foreach (IStar star in stars)
            {
                double x, y;

                GetOnPlateCoordinates(star.RADeg, star.DEDeg, modelConfig, out x, out y);

                if (x < 0 || x > modelConfig.FrameWidth || y < 0 || y > modelConfig.FrameHeight)
                {
                    continue;
                }

                float starMag = GetStarMag(star, modelConfig.PhotometricFilter);
                float iMax    = ModelStarAmplitude(star, starMag, modelConfig, pixmap.BitPixCamera, pixmap.MaxSignalValue);

                if (!float.IsNaN(iMax))
                {
                    VideoModelUtils.GenerateStar(pixmap, (float)x, (float)y, (float)modelConfig.FWHM, iMax, 0 /*Use Gaussian */);

                    if (modelConfig.CheckMagnitudes)
                    {
                        var image = new AstroImage(pixmap);
                        uint[,] data             = image.GetMeasurableAreaPixels((int)x, (int)y, 17);
                        uint[,] backgroundPixels = image.GetMeasurableAreaPixels((int)x, (int)y, 35);

                        PSFFit fit = new PSFFit((int)x, (int)y);
                        fit.Fit(data);

                        var result = mea.MeasureObject(new ImagePixel(x, y), data, backgroundPixels, pixmap.BitPixCamera,
                                                       TangraConfig.PreProcessingFilter.NoFilter,
                                                       TangraConfig.PhotometryReductionMethod.AperturePhotometry, TangraConfig.PsfQuadrature.NumericalInAperture,
                                                       TangraConfig.PsfFittingMethod.DirectNonLinearFit,
                                                       apertureSize, modelConfig.FWHM, (float)modelConfig.FWHM,
                                                       new FakeIMeasuredObject(fit),
                                                       null, null,
                                                       false);

                        if (result == NotMeasuredReasons.TrackedSuccessfully && !mea.HasSaturatedPixels)
                        {
                            // Add value for fitting
                            measurements.Add(star, mea.TotalReading - mea.TotalBackground);
                        }
                    }
                }
            }

            if (modelConfig.CheckMagnitudes)
            {
                CalculateGagnitudeFit(measurements, modelConfig.BVSlope);
            }
        }
Esempio n. 29
0
        public uint[,] measurer_GetImagePixelsCallback(int x, int y, int matrixSize)
        {
            AstroImage currentAstroImage = m_VideoController.GetCurrentAstroImage(false);

            return(currentAstroImage.GetMeasurableAreaPixels(x, y, matrixSize));
        }
Esempio n. 30
0
        public void NextFrame(int frameNo, MovementType movementType, bool isLastFrame, AstroImage astroImage, int firstFrameInIntegrationPeriod, string fileName)
        {
            m_ControlPanel.NextFrame(frameNo, m_Status);

            if (m_Status == ConvertVideoToFitsState.Converting)
            {
                var   timestamp       = DateTime.MinValue;
                float exposureSeconds = 0;

                if (m_VideoController.HasTimestampOCR())
                {
                    m_OCRedTimeStamp = m_VideoController.OCRTimestamp();

                    timestamp = m_OCRedTimeStamp;
                    if (m_AttachDateToOCR.HasValue)
                    {
                        timestamp = m_AttachDateToOCR.Value.Date.Add(timestamp.TimeOfDay);
                        if (m_PrevOCRedTimeStamp.HasValue && m_PrevOCRedTimeStamp.Value > timestamp &&
                            timestamp.Hour == 23 && timestamp.Hour == 0)
                        {
                            timestamp         = timestamp.AddDays(1);
                            m_AttachDateToOCR = m_AttachDateToOCR.Value.AddDays(1);
                        }
                    }

                    if (m_PrevOCRedTimeStamp.HasValue)
                    {
                        exposureSeconds = (float)new TimeSpan(timestamp.Ticks - m_PrevOCRedTimeStamp.Value.Ticks).TotalSeconds;
                    }
                    else
                    {
                        var nextTimeStamp = m_VideoController.GetNextFrameOCRTimestamp();
                        if (nextTimeStamp != DateTime.MinValue)
                        {
                            exposureSeconds = (float)new TimeSpan(nextTimeStamp.TimeOfDay.Ticks - timestamp.TimeOfDay.Ticks).TotalSeconds;
                        }
                    }
                    m_PrevOCRedTimeStamp = timestamp;
                }
                else
                {
                    if (m_VideoController.HasEmbeddedTimeStamps())
                    {
                        timestamp       = astroImage.Pixelmap.FrameState.CentralExposureTime;
                        exposureSeconds = astroImage.Pixelmap.FrameState.ExposureInMilliseconds / 1000.0f;
                    }
                    else
                    {
                        timestamp       = m_StartFrameTime.AddTicks((long)(frameNo - m_StartTimeFrame) * (m_EndFrameTime.Ticks - m_StartFrameTime.Ticks) / (m_EndTimeFrame - m_StartTimeFrame));
                        exposureSeconds = (float)(new TimeSpan((m_EndFrameTime.Ticks - m_StartFrameTime.Ticks) / (m_EndTimeFrame - m_StartTimeFrame)).TotalSeconds);
                    }
                }

                m_ConvertVideoToFitsController.ProcessFrame(frameNo, astroImage, timestamp, exposureSeconds);

                if (isLastFrame || m_LastFrame == frameNo)
                {
                    m_ConvertVideoToFitsController.FinishExport();
                    m_ControlPanel.ExportFinished();
                    m_Status = ConvertVideoToFitsState.Finished;
                    m_VideoController.ShowMessageBox("Export completed.", "Tangra", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }

                if (m_LastFrame == frameNo)
                {
                    m_VideoController.StopVideo();
                }
            }
        }
Esempio n. 31
0
        public StarMagnitudeFit(
            AstroImage astroImage,
            int bitPix,
            List <double> intencities,
            List <double> magnitudes,
            List <double> colours,
            List <IStar> starNumbers,
            List <PSFFit> psfGaussians,
            List <double> profileFittedAmplitudes,
            List <bool> saturatedFlags,
            double a, double b, double c, float encodingGamma, TangraConfig.KnownCameraResponse reverseCameraResponse, int excludedStars,
            TangraConfig.PreProcessingFilter filter, double empericalFWHM,
            TangraConfig.PhotometryReductionMethod photometryReductionMethod,
            TangraConfig.BackgroundMethod photometryBackgroundMethod,
            TangraConfig.PsfQuadrature psfQuadrature,
            TangraConfig.PsfFittingMethod psfFittingMethod,
            MeasurementsHelper measurer,
            float?aperture)
        {
            m_CurrentAstroImage       = astroImage;
            m_BitPix                  = bitPix;
            m_Intencities             = intencities;
            m_Magnitudes              = magnitudes;
            m_Colours                 = colours;
            m_Residuals               = new List <double>();
            m_StarNumbers             = starNumbers;
            m_PSFGaussians            = psfGaussians;
            m_EncodingGamma           = encodingGamma;
            m_ReverseCameraResponse   = reverseCameraResponse;
            m_ExcludedStars           = excludedStars;
            m_SaturatedFlags          = saturatedFlags;
            m_ProfileFittedAmplitudes = profileFittedAmplitudes;

            m_Sigma = 0;
            for (int i = 0; i < intencities.Count; i++)
            {
                double computed = a * -2.5 * Math.Log10(intencities[i]) + b * colours[i] + c;
                double diff     = Math.Abs(computed - magnitudes[i]);
                m_Residuals.Add(diff);

                m_Sigma += diff * diff;
            }
            m_Sigma = Math.Sqrt(m_Sigma / (m_Residuals.Count - 1));

            m_Filter                     = filter;
            m_EmpericalFWHM              = empericalFWHM;
            m_PhotometryReductionMethod  = photometryReductionMethod;
            m_PhotometryBackgroundMethod = photometryBackgroundMethod;
            m_PsfQuadrature              = psfQuadrature;
            m_PsfFittingMethod           = psfFittingMethod;

            m_A = a;
            m_B = b;
            m_C = c;

            m_Measurer            = measurer.Clone();
            m_MeasurementAperture = aperture;

            m_Sigma  = 0;
            m_MinRes = double.MaxValue;
            m_MaxRes = double.MinValue;
            m_MinMag = double.MaxValue;
            m_MaxMag = double.MinValue;
            for (int i = 0; i < m_Residuals.Count; i++)
            {
                double res = m_Residuals[i];

                m_Sigma += res * res;
                if (m_MinRes > res)
                {
                    m_MinRes = res;
                }
                if (m_MaxRes < res)
                {
                    m_MaxRes = res;
                }

                double mag = m_Magnitudes[i];
                if (m_MinMag > mag)
                {
                    m_MinMag = mag;
                }
                if (m_MaxMag < mag)
                {
                    m_MaxMag = mag;
                }
            }

            m_Sigma = Math.Sqrt(m_Sigma / m_Residuals.Count);
        }