Ejemplo n.º 1
0
 public void TestCriticalPointCalculation()
 {
     foreach (int key in s_T_Coeff_95.Keys)
     {
         var coeff = TDistribution.CalculateCriticalValue(key, (1 - 0.95), 0.0001);
         Assert.AreEqual(s_T_Coeff_95[key], coeff, 0.002);
     }
 }
Ejemplo n.º 2
0
        public ProcessingReturnValues FitAndPlotSlowMotion(
            Dictionary <int, SingleMultiFrameMeasurement> measurements,
            FlybyMeasurementContext meaContext,
            GetProcessingValueCallback getValueCallback,
            Graphics g, FlybyPlottingContext plottingContext, float xScale, float yScale, int imageWidth)
        {
            // Compute median, use median based exclusion rules
            // Report the median position for the time at the middle of the measured interval
            // Do not expect elongated image (no corrections from the exposure)
            // May apply instrumental delay corrections for the frame time

            var rv = new ProcessingReturnValues();

            double sum           = 0;
            double userSum       = 0;
            double stdDevUserSum = 0;
            int    numFramesUser = 0;

            double userMidFrom = meaContext.UserMidValue - meaContext.MaxStdDev;
            double userMidTo   = meaContext.UserMidValue + meaContext.MaxStdDev;

            rv.EarliestFrame = int.MaxValue;
            rv.LatestFrame   = int.MinValue;

            List <double> medianList              = new List <double>();
            List <double> medianWeightsList       = new List <double>();
            var           minPosUncertaintyArcSec = TangraConfig.Settings.Astrometry.AssumedPositionUncertaintyPixels * meaContext.ArsSecsInPixel;

            foreach (SingleMultiFrameMeasurement measurement in measurements.Values)
            {
                float            x         = (measurement.FrameNo - meaContext.MinFrameNo) * xScale + 5;
                ProcessingValues val       = getValueCallback(measurement);
                double           valueFrom = val.Value - val.StdDev;
                double           valueTo   = val.Value + val.StdDev;

                float yFrom = (float)(valueFrom - plottingContext.MinValue) * yScale + 5;
                float yTo   = (float)(valueTo - plottingContext.MinValue) * yScale + 5;

                sum += val.Value;

                Pen mPen = plottingContext.IncludedPen;
                if (!double.IsNaN(meaContext.UserMidValue))
                {
                    if ((valueFrom >= userMidFrom && valueFrom <= userMidTo) ||
                        (valueTo >= userMidFrom && valueTo <= userMidTo))
                    {
                        numFramesUser++;
                        userSum += val.Value;
                        medianList.Add(val.Value);
                        medianWeightsList.Add(ComputePositionWeight(val.StdDev, measurement, minPosUncertaintyArcSec, WeightingMode.SNR));

                        stdDevUserSum += val.StdDev * val.StdDev;
                        if (rv.EarliestFrame > measurement.FrameNo)
                        {
                            rv.EarliestFrame = measurement.FrameNo;
                        }
                        if (rv.LatestFrame < measurement.FrameNo)
                        {
                            rv.LatestFrame = measurement.FrameNo;
                        }
                    }
                    else
                    {
                        mPen = plottingContext.ExcludedPen;
                    }
                }


                g.DrawLine(mPen, x, yFrom, x, yTo);
                g.DrawLine(mPen, x - 1, yFrom, x + 1, yFrom);
                g.DrawLine(mPen, x - 1, yTo, x + 1, yTo);
            }

            if (!double.IsNaN(meaContext.UserMidValue) && numFramesUser > 0)
            {
                double average = userSum / numFramesUser;
                double err     = Math.Sqrt(stdDevUserSum) / (numFramesUser - 1);
                float  yAve    = (float)(average - plottingContext.MinValue) * yScale + 5;
                g.DrawLine(plottingContext.AveragePen, 5, yAve - 1, imageWidth - 5, yAve - 1);
                g.DrawLine(plottingContext.AveragePen, 5, yAve, imageWidth - 5, yAve);
                g.DrawLine(plottingContext.AveragePen, 5, yAve + 1, imageWidth - 5, yAve + 1);

                float yMin = (float)(userMidFrom - plottingContext.MinValue) * yScale + 5;
                float yMax = (float)(userMidTo - plottingContext.MinValue) * yScale + 5;
                g.DrawLine(plottingContext.AveragePen, 5, yMin, imageWidth - 5, yMin);
                g.DrawLine(plottingContext.AveragePen, 5, yMax, imageWidth - 5, yMax);

                double median;
                double medianWeight;

                WeightedMedian(Tuple.Create(medianList, medianWeightsList), out median, out medianWeight);

                double standardMedian = medianList.Median();

                Trace.WriteLine(string.Format("{0}; Included: {1}; Average: {2}; Wighted Median: {3}; Standard Median: {4}",
                                              meaContext.UserMidValue.ToString("0.00000"),
                                              numFramesUser, AstroConvert.ToStringValue(average, "+HH MM SS.TTT"),
                                              AstroConvert.ToStringValue(median, "+HH MM SS.TTT"),
                                              AstroConvert.ToStringValue(standardMedian, "+HH MM SS.TTT")));

                rv.FittedValue = median;

                var stdDevArcSec = 3600 * Math.Sqrt(medianList.Sum(x => (x - median) * (x - median)) / (medianList.Count - 1));
                var tCoeff95     = TDistribution.CalculateCriticalValue(medianList.Count, (1 - 0.95), 0.0001);
                var error95      = 1.253 * tCoeff95 * stdDevArcSec / Math.Sqrt(medianList.Count);
                rv.FittedValueUncertaintyArcSec = error95;
                rv.IsVideoNormalPosition        = false;
            }
            else
            {
                double average = sum / measurements.Count;
                float  yAve    = (float)(average - plottingContext.MinValue) * yScale + 5;
                g.DrawLine(Pens.WhiteSmoke, 5, yAve, imageWidth - 5, yAve);

                rv.FittedValue = double.NaN;
            }

            return(rv);
        }