Esempio n. 1
0
void InitDE431(const char* filepath)
{
	ephem = jpl_init_ephemeris(filepath, nams, vals);

	if(jpl_init_error_code() != 0)
	{
		StelApp::getInstance().getCore()->setDe431Active(false);
		qDebug() << "Error "<< jpl_init_error_code() << "at DE431 init:" << jpl_init_error_message();
	}
	else
	{
		initDone = true;
		double jd1, jd2;
		jd1=jpl_get_double(ephem, JPL_EPHEM_START_JD);
		jd2=jpl_get_double(ephem, JPL_EPHEM_END_JD);
		qDebug() << "DE431 init successful. startJD=" << QString::number(jd1, 'f', 4) << "endJD=" << QString::number(jd2, 'f', 4);
	}
}
Esempio n. 2
0
int main( const int argc, const char **argv)
{
  char nams[JPL_MAX_N_CONSTANTS][6], buff[102];
  double vals[JPL_MAX_N_CONSTANTS];
  double max_err_found[10][6];
  int line,  n_failures[10];
  size_t i, j;
  unsigned n_constants, n_columns;
  int output_frequency = 100;
  const char *ephfile_name = argv[1];
  double start_jd, end_jd;
  double roundoff_error = 0.;
  bool report_all_errors = false;
  bool pause_on_errors = true;
  FILE *testfile;
  clock_t timer;
  void *ephem;
  const char *test_file_name = NULL;
#if defined( __GNUC__) && !defined( __MINGW32__)
   const char path_separator = '/';
#else
   const char path_separator = '\\';
#endif
   const char *error_messages[7] = {
       "Result outside acceptable error tolerance",
       "Outside date range",
       "Read error",
       "Quantity not in index",
       "? Obsolete error;  shouldn't happen",
       "Invalid index",
       "Seek error" };
   const int n_errors = sizeof( error_messages) / sizeof( error_messages[0]);

/***** Write a fingerprint to the screen. ***********************************/

  setvbuf( stdout, NULL, _IONBF, 0);
  puts("\n JPL test-ephemeris program (v.1.2)\n"
       " C version translated from the original JPL FORTRAN code.\n");

   if( argc < 2)
      error_exit( -1);
   for( i = 0; i < 10; i++)
      for( j = 0; j < 6; j++)
         max_err_found[i][j] = 0.;

   for( i = 2; i < (size_t)argc; i++)
      if( argv[i][0] == '-')
         switch( argv[i][1])
            {
            case 'a': case 'A':
               report_all_errors = true;
               break;
            case 'f': case 'F':
               output_frequency = atoi( argv[i] + 2);
               break;
            case 'n': case 'N':
               pause_on_errors = false;
               break;
            case 't': case 'T':
               test_file_name = argv[i] + 2;
               break;
            default:
               printf( "Unrecognized option '%s'\n", argv[i]);
               error_exit( -2);
               break;
            }

/****** Print the ephemeris constants. **************************************/

  ephem = jpl_init_ephemeris( ephfile_name, nams, vals);
  if( !ephem)
     {
     printf( "Ephemeris file '%s' not loaded\n", ephfile_name);
     printf( "Error code: %d\n", jpl_init_error_code( ));
     error_exit( -2);
     }
   else
      printf( "Ephemeris initialized\n");

   n_constants = (unsigned)jpl_get_long( ephem, JPL_EPHEM_N_CONSTANTS);
   printf( "%u constants\n", n_constants);
   if( n_constants > JPL_MAX_N_CONSTANTS)
      n_constants = JPL_MAX_N_CONSTANTS;
   start_jd = jpl_get_double( ephem, JPL_EPHEM_START_JD),
   end_jd =   jpl_get_double( ephem, JPL_EPHEM_END_JD),
   printf("%.9f  %.9f  %.9f\n", start_jd, end_jd,
                           jpl_get_double( ephem, JPL_EPHEM_STEP));
   n_columns = (n_constants + 1) / 2;
   for( i = 0; i < (size_t)n_columns; i++)
      {
      printf("%.6s  %24.16E",nams[i],vals[i]);
      if( i + n_columns < n_constants)
         printf("   %.6s  %24.16E",nams[i + n_columns],vals[i + n_columns]);
      printf( "\n");
      }

   printf( "emrat = %.15f      AU = %.5f\n",
                           jpl_get_double( ephem, JPL_EPHEM_EARTH_MOON_RATIO),
                           jpl_get_double( ephem, JPL_EPHEM_AU_IN_KM));

/****** Skip the test points file header comments.  *************************/
  if( test_file_name)
     strcpy( buff, test_file_name);
  else
     {
     const char *extension;

     strcpy( buff, ephfile_name);
     for( i = strlen( buff); i && buff[i - 1] != path_separator; i--)
        ;
     strcpy( buff + i, "testpo");
     extension = strchr( ephfile_name + i, '.');
     if( extension)
        strcat( buff + i, extension);
     else
        sprintf( buff + strlen( buff), ".%3ld",
            jpl_get_long( ephem, JPL_EPHEM_EPHEMERIS_VERSION));
     }

  testfile = fopen( buff, "r");
  if( !testfile)
     {
     printf( "Test data file '%s' not found\n", buff);
     error_exit( -3);
     }

   while( fgets( buff, 100, testfile) && memcmp( buff, "EOT", 3))
      ;

   puts(" LINE  JED    t# c# x#  --- JPL value ---   "
          "--- user value --   -- difference --");

   line=0;
   timer = clock( );
   for( i = 0; i < 10; i++)
      n_failures[i] = 0;
   while( fgets( buff, 100, testfile) != NULL)
   {
     int err_code, ntarg, nctr, ncoord;
     double del, et;
     double r[6], xi, xi_computed;
     bool fatal_error = false, report_this_error = false;

/*****  Read a value from the test case; Skip if not within the time-range
        of the present version of the ephemeris.                            */
     line++;
     if( sscanf( buff + 15," %lf %d %d %d %lf", &et, &ntarg, &nctr, &ncoord,
                       &xi) != 5)
        {
        printf( "Failure to parse line %d:\n%s\n", line, buff);
        fatal_error = true;
        }
     else
        {
        err_code = jpl_pleph(ephem, et, ntarg, nctr, r, 1);
        if( err_code > 0 || err_code < -n_errors)
           {
           printf( "Internal error:  unknown error code %d\n", err_code);
           fatal_error = true;
           }
        else if( !roundoff_error)
           {
           char *tptr = strchr( buff + 30, '.');

           assert( tptr);
           tptr++;
           roundoff_error = .5;
           while( *tptr >= '0' && *tptr <= '9')
              {
              tptr++;
              roundoff_error /= 10.;
              }
           }
        }
     if( fatal_error)
        {
        printf( "\nThis error shouldn't happen,  ever.  It indicates a bug\n");
        printf( "that should be fixed.\n");
        printf( "Please contact [email protected] and report this.\n");
        return( -1);
        }
     xi_computed = r[ncoord - 1];
     del = fabs( xi_computed - xi);
     if( err_code)
        {
        n_failures[-err_code]++;
        if( n_failures[-err_code] == 1 || report_all_errors)
           report_this_error = true;
        }
     else
        {
        const double tolerance = max_accepted_error( ntarg, ncoord)
                               + fabs( xi) * 1e-14 + roundoff_error;
        const unsigned idx = (ntarg <= 13 ? 0 : ntarg - 13);

        if( max_err_found[idx][ncoord - 1] < del - tolerance)
           max_err_found[idx][ncoord - 1] = del - tolerance;
        if( del > tolerance)
           {
           n_failures[0]++;
           if( n_failures[-err_code] == 1 || report_all_errors)
              {
              report_this_error = true;
              printf( "*****  warning : next difference >= tolerance *****\n");
              printf( "%s", buff);
              }
           }
        }

     if( (!err_code && !(line % output_frequency)) || report_this_error)
        printf("%4d %10.1f %2d %2d %2d %25.20f %25.20f %22.20f\n",
               line,et,ntarg,nctr,ncoord,xi, xi_computed, xi_computed - xi);
     if( report_this_error)
        {
        printf( "Error message: '%s'\n", error_messages[-err_code]);
        if( err_code == JPL_EPH_OUTSIDE_RANGE)
           {
           const double J2000 = 2451545.;

           printf( "WARNING:  The test file tests items outside the range\n");
           printf( "of this ephemeris!\n");
           printf( "The input ephemeris file covers years from %.1f to %.1f.\n",
                 2000. + (start_jd - J2000) / 365.25,
                 2000. + (end_jd - J2000) / 365.25);
           printf( "The test is for the year %.1f\n",
                 2000. + (et - J2000) / 365.25);
           printf( "It's common for DE files to be built that cover a subset of the\n");
           printf( "range of the original ephemerides,  so this may not be an error.\n");
           }
        if( !report_all_errors)
           {
           printf( "  Further errors of this type won't be shown,  but you'll get a count\n");
           printf( "  of how many are found. (Use the '-a' switch to report all errors.)\n");
           }
        if( pause_on_errors)
           {
           printf( "  Hit any key:\n");
           getchar( );
           }
        }
   }
   for( i = 0; i < 10; i++)
      for( j = 0; j < 6; j++)
         if( max_err_found[i][j])
            printf( "%d %d %.8e %c\n", (int)i, (int)j + 1, max_err_found[i][j],
                       (max_err_found[i][j] > 0.) ? '*' : ' ');

   printf( "%d lines read and tested in %.3f seconds\n", line,
           (double)( clock( ) - timer) / (double)CLOCKS_PER_SEC);
   for( i = 0; i < (size_t)n_errors; i++)
      if( n_failures[i])
         printf( "%d lines failed with error code %d ('%s').\n",
                          n_failures[i], -(int)i, error_messages[i]);
   fclose( testfile);
   jpl_close_ephemeris( ephem);
   return( 0);
}
Esempio n. 3
0
static int planet_posn_raw( int planet_no, const double jd,
                            double *vect_2000)
{
   static void *ps_1996_data[10];
   const int jpl_center = 11;         /* default to heliocentric */
   int i, rval = 0;
   static const char *jpl_filename = NULL;
   static void *jpl_eph = NULL;
   const int bc405_start = 100;
   const int calc_vel = (planet_no & PLANET_POSN_VELOCITY_FLAG) ? 1 : 0;

   planet_no &= ~PLANET_POSN_VELOCITY_FLAG;
   if( !planet_no)            /* the sun */
      {
      vect_2000[0] = vect_2000[1] = vect_2000[2] = 0.;
      if( !jd && jpl_eph)       /* return version data: */
         {
         vect_2000[0] = (double)jpl_get_long( jpl_eph, JPL_EPHEM_EPHEMERIS_VERSION);
         vect_2000[1] = jpl_get_double( jpl_eph, JPL_EPHEM_START_JD);
         vect_2000[2] = jpl_get_double( jpl_eph, JPL_EPHEM_END_JD);
         }
      return( 0);
      }

   if( planet_no >= bc405_start && planet_no < bc405_start + 300)
      {
      double temp_loc[4];

      rval = asteroid_position_raw( planet_no - bc405_start, jd, temp_loc);
      if( debug_level > 8)
         debug_printf( "JD %f, minor planet %d: (%f %f %f)\n",
                     jd, planet_no, temp_loc[0], temp_loc[1], temp_loc[2]);
      memcpy( vect_2000, temp_loc, 3 * sizeof( double));
      return( rval);
      }

   if( !jpl_filename)
      {
      FILE *ifile;

#if defined (_WIN32) || defined( __WATCOMC__)
      jpl_filename = get_environment_ptr( "JPL_FILENAME");
#else
      jpl_filename = get_environment_ptr( "LINUX_JPL_FILENAME");
#endif
      if( *jpl_filename)
         jpl_eph = jpl_init_ephemeris( jpl_filename, NULL, NULL);
      if( !jpl_eph)
         if( (ifile = fopen_ext( "jpl_eph.txt", "fcrb")) != NULL)
            {
            char buff[100];

            while( !jpl_eph && fgets_trimmed( buff, sizeof( buff), ifile))
               if( *buff && *buff != ';')
                  {
                  jpl_eph = jpl_init_ephemeris( buff, NULL, NULL);
                  if( !jpl_eph)
                     {
                     char tname[255];

                     make_config_dir_name( tname, buff);
                     jpl_eph = jpl_init_ephemeris( tname, NULL, NULL);
                     }
                  }
            if( debug_level)
               debug_printf( "Ephemeris file %s\n", buff);
            fclose( ifile);
            }
      if( debug_level && jpl_eph)
         {
         debug_printf( "\nEphemeris time span years %.3f to %.3f\n",
               (jpl_get_double( jpl_eph, JPL_EPHEM_START_JD) - J0) / 365.25,
               (jpl_get_double( jpl_eph, JPL_EPHEM_END_JD)   - J0) / 365.25);
         debug_printf( "Ephemeris version %ld\n", jpl_get_long( jpl_eph, JPL_EPHEM_EPHEMERIS_VERSION));
         debug_printf( "Kernel size %ld, record size %ld, swap_bytes %ld\n",
               jpl_get_long( jpl_eph, JPL_EPHEM_KERNEL_SIZE),
               jpl_get_long( jpl_eph, JPL_EPHEM_KERNEL_RECORD_SIZE),
               jpl_get_long( jpl_eph, JPL_EPHEM_KERNEL_SWAP_BYTES));
         debug_printf( "ncon = %ld AU=%f emrat = %f\n",
               jpl_get_long( jpl_eph, JPL_EPHEM_N_CONSTANTS),
               jpl_get_double( jpl_eph, JPL_EPHEM_AU_IN_KM),
               jpl_get_double( jpl_eph, JPL_EPHEM_EARTH_MOON_RATIO));
         }
      }

   if( jpl_eph)
      {
      double state[6];            /* DE gives both posn & velocity */
      int failure_code;

      if( planet_no < 0)          /* flag to unload everything */
         {
         jpl_close_ephemeris( jpl_eph);
         jpl_eph = NULL;
         jpl_filename = NULL;
         return( 0);
         }
      else if( planet_no == 10)
         failure_code = jpl_pleph( jpl_eph, jd, 10, 3, state, calc_vel);
      else
         failure_code = jpl_pleph( jpl_eph, jd,
              (planet_no == 3) ? 13 : planet_no, jpl_center, state, calc_vel);
      if( !failure_code)         /* we're done */
         {
         if( debug_level > 8)
            debug_printf( "JD %f, planet %d: (%f %f %f)\n",
                     jd, planet_no, state[0], state[1], state[2]);
         equatorial_to_ecliptic( state);
         memcpy( vect_2000, state + calc_vel, 3 * sizeof( double));
         return( 0);
         }
      else
         if( debug_level)
            debug_printf( "Failed: JD %f, planet %d, code %d\n",
                           jd, planet_no, failure_code);
      }

   if( planet_no == 10)        /* the moon */
      {
      double tloc[4];

      if( !compute_elp_xyz( NULL, (jd - J2000) / 36525., 0., tloc))
         for( i = 0; i < 3; i++)
            vect_2000[i] = tloc[i] / AU_IN_KM;
      else
         {
         static int first_time = 1;

         rval = -3;
         if( first_time)
            generic_message_box( get_find_orb_text( 2019), "o");
         first_time = 0;
         compute_rough_planet_loc( (jd - J2000) / 36525., 10, vect_2000);
         }
      return( rval);
      }

   if( planet_no < 0)          /* flag to unload everything */
      {
      for( i = 0; i < 10; i++)
         if( ps_1996_data[i])
            {
            unload_ps1996_series( ps_1996_data[i]);
            ps_1996_data[i] = NULL;
            }
      return( 0);
      }

   if( !ps_1996_data[planet_no])
      ps_1996_data[planet_no] = load_ps1996_series( NULL, jd, planet_no);

   if( !ps_1996_data[planet_no])
      rval = -1;
   else if( get_ps1996_position( jd, ps_1996_data[planet_no], vect_2000, 0))
      {
      unload_ps1996_series( ps_1996_data[planet_no]);
      ps_1996_data[planet_no] = load_ps1996_series( NULL, jd, planet_no);
      if( !ps_1996_data[planet_no])
         rval = -2;
      else if( get_ps1996_position( jd, ps_1996_data[planet_no], vect_2000, 0))
         rval = -3;
      }

   if( !rval)
      equatorial_to_ecliptic( vect_2000);
   else
      {
      static int first_time = 1;

      if( first_time)
         {
         generic_message_box( get_find_orb_text( 2020), "o");
         debug_printf( "Loading ps_1996: rval %d, planet %d, JD %f\n",
                  rval, planet_no, jd);
         }
      first_time = 0;
      if( planet_no > 0 && planet_no < 9)
         compute_rough_planet_loc( (jd - J2000) / 36525., planet_no, vect_2000);
      }

   return( rval);
}
Esempio n. 4
0
int merge_jpl_files( const char *output_filename, const int n_input_files,
                     const char **input_filenames)
{
   void *jpl_eph = jpl_init_ephemeris( input_filenames[0], NULL, NULL);
   int i, j, de_number, kernel_size, kernel_days, rval = 0;
   FILE *ifile, *ofile = NULL;
   struct jpl_file *idata;
   char *buff = NULL;

   if( !jpl_eph)
      return( MERGE_ERR_INITIALIZING);

   de_number = (int)jpl_get_long( jpl_eph, JPL_EPHEM_EPHEMERIS_VERSION);
   kernel_days = (int)( jpl_get_double( jpl_eph, JPL_EPHEM_STEP) + .5);
   kernel_size = jpl_get_long( jpl_eph, JPL_EPHEM_KERNEL_SIZE);
   jpl_close_ephemeris( jpl_eph);

   idata = (struct jpl_file *)calloc( n_input_files, sizeof( struct jpl_file));
   if( !idata)
      return( MERGE_ERR_INITIALIZING);

   for( i = 0; !rval && i < n_input_files; i++)
      {
      ifile = fopen( input_filenames[i], "rb");
      if( !ifile)
         rval = MERGE_ERR_OPENING;
      else
         {
         if( fread( idata[i].header, 84, 3, ifile) != 3)
            rval = MERGE_ERR_READING_HEADER;
         fclose( ifile);
         if( !rval)
            {
            if( memcmp( idata[i].header, "JPL Planetary Ephemeris", 23))
               rval = MERGE_ERR_NOT_A_JPL_EPHEM;
            else if( de_number != atoi( idata[i].header + 26))
               {
               printf( "You can't merge files from different DE ephemerides\n");
               printf( "'%s' is from DE-%d\n", input_filenames[i],
                                                atoi( idata[i].header + 26));
               printf( "'%s' is from DE-%d\n", input_filenames[0], de_number);
               rval = MERGE_ERR_MISMATCHED_VERSIONS;
               }
            }
         idata[i].jd_start = atol( idata[i].header + 102);
         idata[i].jd_end   = atol( idata[i].header + 186);
         idata[i].filename = input_filenames[i];
         }
      }

   if( rval)
      {
      free( idata);
      return( rval);
      }
                   /* OK, now sort by date: */
   for( i = 0; i < n_input_files; i++)
      for( j = 0; j < i; j++)
         if( idata[i].jd_start < idata[j].jd_start)
            {
            struct jpl_file temp = idata[i];

            idata[i] = idata[j];
            idata[j] = temp;
            }
   printf( "Merging:\nJD Start  JD End     Filename\n");
   for( i = 0; i < n_input_files; i++)
      printf( "%8ld.5 %8ld.5 %s\n", idata[i].jd_start, idata[i].jd_end,
                                                       idata[i].filename);
                  /* Check to be sure the files overlap: */
   for( i = 0; i < n_input_files - 1; i++)
      if( idata[i + 1].jd_start > idata[i].jd_end)
         {
         printf( "ERROR:  there is a gap between '%s' and '%s'.\n",
                        idata[i].filename, idata[i + 1].filename);
         rval = MERGE_ERR_GAP_IN_DATA;
         }

   if( !rval)
      {
      ofile = fopen( output_filename, "wb");
      if( !ofile)
         {
         printf( "Couldn't open output file '%s'\n", output_filename);
         rval = MERGE_ERR_OPENING_2;
         }
      }
   if( !rval)
      {
      buff = (char *)malloc( kernel_size);
      if( !buff)
         rval = MERGE_ERR_OUT_OF_MEMORY;
      }
   for( i = 0; !rval && i < n_input_files; i++)
      {
      int n_blocks;

      ifile = fopen( idata[i].filename, "rb");
      if( !ifile)
         rval = MERGE_ERR_OPENING_3;
      if( !i)
         for( j = 0; !rval && j < 2; j++)       /* copy out two header blocks */
            {
            if( fread( buff, kernel_size, 1, ifile) != 1)
               rval = MERGE_ERR_DATA_READ;
            else if( fwrite( buff, kernel_size, 1, ofile) != 1)
               rval = MERGE_ERR_DATA_WRITE;
            }
         else
            fseek( ifile, 2L * kernel_size, SEEK_SET);
      if( i == n_input_files - 1)
         n_blocks = (idata[i].jd_end - idata[i].jd_start) / kernel_days;
      else
         n_blocks = (idata[i + 1].jd_start - idata[i].jd_start) / kernel_days;
      while( !rval && n_blocks--)
         {
         if( fread( buff, kernel_size, 1, ifile) != 1)
            rval = MERGE_ERR_DATA_READ_2;
         else if( fwrite( buff, kernel_size, 1, ofile) != 1)
            rval = MERGE_ERR_DATA_WRITE_2;
         }
      if( !rval && i == n_input_files - 1)      /* patch up ending date */
         {
         fseek( ofile, 2L * 84L, SEEK_SET);
         if( fwrite( idata[i].header + 2 * 84, 84, 1, ofile) != 1)
            rval = MERGE_ERR_DATA_WRITE_HEADER;
         fseek( ifile, 2660L, SEEK_SET);
         if( !rval)
            {
            if( fread( buff, 8, 1, ifile) != 1)
               rval = MERGE_ERR_DATA_READ_3;
            fseek( ofile, 2660L, SEEK_SET);
            if( !rval && fwrite( buff, 8, 1, ofile) != 1)
               rval = MERGE_ERR_DATA_WRITE_3;
            }
         }
      fclose( ifile);
      }
   // free memory and close filehandles
   if( buff)
      free( buff);
   free( idata);
   if( ofile)
      fclose( ofile);
   return( rval);
}