示例#1
0
        private void ReadPlanetConstants(SEFileData data)
        {
            foreach (var ipli in data.PlanetNumbers)
            {
                var pdp = new PlanetData();

                pdp.InternalBodyNumber = ipli;
                pdp.FileIndexStart     = ReadInt32();
                pdp.Flags = (PlanetFlags)_stream.ReadByte();
                pdp.CoefficientsNumber  = _stream.ReadByte();
                pdp.NormalizationFactor = ReadInt32() / 1000.0;
                var doubles = ReadDoubles(10);
                pdp.StartDate         = JulianDayNumber.FromRaw(doubles[0]);
                pdp.EndDate           = JulianDayNumber.FromRaw(doubles[1]);
                pdp.SegmentSize       = doubles[2];
                pdp.IndexEntriesCount = (int)((doubles[1] - doubles[0] + 0.1) / doubles[2]);
                pdp.ElementsEpoch     = doubles[3];
                pdp.Prot     = doubles[4];
                pdp.Dprot    = doubles[5];
                pdp.Qrot     = doubles[6];
                pdp.Dqrot    = doubles[7];
                pdp.Perigee  = doubles[8];
                pdp.DPerigee = doubles[9];
                if (pdp.Flags.HasFlag(PlanetFlags.Ellipse))
                {
                    pdp.ReferenceEllipseCoefficients = ReadDoubles(2 * pdp.CoefficientsNumber);
                }

                var index = ipli >= SEConsts.AseroidOffset
                                        ? InternalPlanets.AnyBody
                                        : (InternalPlanets)ipli;
                data.PlanetsData[index] = pdp;
            }
        }
示例#2
0
        /// <summary>
        /// start and end epoch of file
        /// </summary>
        private (JulianDayNumber, JulianDayNumber) ReadFilePeriod()
        {
            var    buff  = ReadDoubles(2);
            double start = buff[0];
            double end   = buff[1];

            return(JulianDayNumber.FromRaw(start), JulianDayNumber.FromRaw(end));
        }
        /// <summary>
        /// Stephenson & Morrison (2004)
        /// </summary>
        public static double Calc(JulianDayNumber tjd, double tid_acc)
        {
            double ans = 0, ans2, ans3;
            double p, B, dd;
            double tjd0;
            int    iy;
            double Y = tjd.GetGregorianYear();

            /* before -1000:
             * formula by Stephenson & Morrison (2004; p. 335) but adjusted to fit the
             * starting point of table dt2. */
            if (Y < DeltaTTabulated.Tab2Start)
            {
                // before -1000
                ans = DeltaTLongtermMorrisonStephenson.Calc(tjd);
                ans = TidalAcceleration.AdjustForTidalAcceleration(ans, Y, tid_acc, TidalAccelerationMode.Const26, false);
                /* transition from formula to table over 100 years */
                if (Y >= DeltaTTabulated.Tab2Start - 100)
                {
                    /* starting value of table dt2: */
                    ans2 = TidalAcceleration.AdjustForTidalAcceleration(DeltaTTabulated.dt2[0], DeltaTTabulated.Tab2Start, tid_acc, TidalAccelerationMode.Const26, false);
                    /* value of formula at epoch TAB2_START */

                    /* B = (TAB2_START - LTERM_EQUATION_YSTART) * 0.01;
                     * ans3 = -20 + LTERM_EQUATION_COEFF * B * B;*/
                    tjd0 = (DeltaTTabulated.Tab2Start - 2000) * 365.2425 + (double)JulianDayNumber.J2000;
                    ans3 = DeltaTLongtermMorrisonStephenson.Calc(JulianDayNumber.FromRaw(tjd0));
                    ans3 = TidalAcceleration.AdjustForTidalAcceleration(ans3, Y, tid_acc, TidalAccelerationMode.Const26, false);
                    dd   = ans3 - ans2;
                    B    = (Y - (DeltaTTabulated.Tab2Start - 100)) * 0.01;
                    /* fit to starting point of table dt2. */
                    ans -= dd * B;
                }
            }

            /* between -1000 and 1600:
             * linear interpolation between values of table dt2 (Stephenson & Morrison 2004) */
            if (Y >= DeltaTTabulated.Tab2Start && Y < DeltaTTabulated.Tab2End)
            {
                double Yjul = tjd.GetJulianYear();
                p   = Math.Floor(Yjul);
                iy  = (int)((p - DeltaTTabulated.Tab2Start) / DeltaTTabulated.Tab2Step);
                dd  = (Yjul - (DeltaTTabulated.Tab2Start + DeltaTTabulated.Tab2Step * iy)) / DeltaTTabulated.Tab2Step;
                ans = DeltaTTabulated.dt2[iy] + (DeltaTTabulated.dt2[iy + 1] - DeltaTTabulated.dt2[iy]) * dd;
                /* correction for tidal acceleration used by our ephemeris */
                ans = TidalAcceleration.AdjustForTidalAcceleration(ans, Y, tid_acc, TidalAccelerationMode.Const26, false);
            }
            ans /= 86400.0;
            return(ans);
        }
示例#4
0
        /// <summary>
        /// Fetch chebyshew coefficients from sweph file
        /// </summary>
        /// <param name="pdp">Planet</param>
        /// <param name="jd">Time</param>
        /// <param name="epsilonJ2000">Epsilon for J2000</param>
        /// <see cref="get_new_segment"/>
        internal SEFileSegment ReadSegment(PlanetData pdp, JulianDayNumber jd, Epsilon epsilonJ2000)
        {
            int segmentNumber = (int)((jd - pdp.StartDate).Raw / pdp.SegmentSize);
            var segmentStart  = pdp.StartDate + JulianDayNumber.FromRaw(pdp.SegmentSize * segmentNumber);

            var fpos = pdp.FileIndexStart + segmentNumber * 3;

            fpos = ReadInt32From3Bytes(fpos);
            _stream.Seek(fpos, SeekOrigin.Begin);

            var rmax = pdp.NormalizationFactor;

            double[] segp = new double[pdp.CoefficientsNumber * 3];
            // read coefficients for 3 coordinates
            for (var icoord = 0; icoord < 3; icoord++)
            {
                var idbl = icoord * pdp.CoefficientsNumber;
                // first read header
                // first bit indicates number of sizes of packed coefficients
                int   nco;
                int   nsizes;
                int[] nsize = new int[6];
                var   c     = ReadData(1, 2);
                if ((c[0] & 128) > 0)
                {
                    var c2 = ReadData(1, 2);
                    nsizes   = 6;
                    nsize[0] = c[1] / 16;
                    nsize[1] = c[1] % 16;
                    nsize[2] = c2[0] / 16;
                    nsize[3] = c2[0] % 16;
                    nsize[4] = c2[1] / 16;
                    nsize[5] = c2[1] % 16;
                    nco      = nsize[0] + nsize[1] + nsize[2] + nsize[3] + nsize[4] + nsize[5];
                }
                else
                {
                    nsizes   = 4;
                    nsize[0] = c[0] / 16;
                    nsize[1] = c[0] % 16;
                    nsize[2] = c[1] / 16;
                    nsize[3] = c[1] % 16;
                    nco      = nsize[0] + nsize[1] + nsize[2] + nsize[3];
                }
                // there may not be more coefficients than interpolation order + 1
                if (nco > pdp.CoefficientsNumber)
                {
                    throw new FormatException($"Error in ephemeris file: {nco} coefficients instead of {pdp.CoefficientsNumber}");
                }

                // now unpack
                for (var i = 0; i < nsizes; i++)
                {
                    if (nsize[i] == 0)
                    {
                        continue;
                    }

                    if (i < 4)
                    {
                        int j     = 4 - i;
                        int k     = nsize[i];
                        var longs = ReadUints(j, k);
                        for (int m = 0; m < k; m++)
                        {
                            if ((longs[m] & 1) > 0)                             // will be negative
                            {
                                segp[idbl] = -(((longs[m] + 1) / 2) / 1e+9 * rmax / 2);
                            }
                            else
                            {
                                segp[idbl] = (longs[m] / 2) / 1e+9 * rmax / 2;
                            }
                            idbl++;
                        }
                    }
                    else if (i == 4)                     // half byte packing
                    {
                        int k     = (nsize[i] + 1) / 2;
                        var longs = ReadUints(1, k);
                        for (int m = 0, j = 0;
                             m < k && j < nsize[i];
                             m++)
                        {
                            for (int n = 0, o = 16;
                                 n < 2 && j < nsize[i];
                                 n++, j++, idbl++, longs[m] %= (uint)o, o /= 16)
                            {
                                if ((longs[m] & o) > 0)
                                {
                                    segp[idbl] = -(((longs[m] + o) / o / 2) * rmax / 2 / 1e+9);
                                }
                                else
                                {
                                    segp[idbl] = (longs[m] / o / 2) * rmax / 2 / 1e+9;
                                }
                            }
                        }
                    }
                    else if (i == 5)                     // quarter byte packing
                    {
                        int k     = (nsize[i] + 3) / 4;
                        var longs = ReadUints(1, k);
                        for (int m = 0, j = 0;
                             m < k && j < nsize[i];
                             m++)
                        {
                            for (int n = 0, o = 64;
                                 n < 4 && j < nsize[i];
                                 n++, j++, idbl++, longs[m] %= (uint)o, o /= 4)
                            {
                                if ((longs[m] & o) > 0)
                                {
                                    segp[idbl] = -(((longs[m] + o) / o / 2) * rmax / 2 / 1e+9);
                                }
                                else
                                {
                                    segp[idbl] = (longs[m] / o / 2) * rmax / 2 / 1e+9;
                                }
                            }
                        }
                    }
                }
            }

            int evaluateCoefficientsCount = pdp.Flags.HasFlag(PlanetFlags.Rotate)
                                ? RotateBack(pdp, segmentStart, segp, epsilonJ2000)
                                : pdp.CoefficientsNumber;
            var segment = new SEFileSegment(segmentStart, JulianDayNumber.FromRaw(pdp.SegmentSize), segp, evaluateCoefficientsCount);

            return(segment);
        }