JEphem Informatic Trail build classes source code BuildVSOP87.java
//*********************************************************************************
// class BuildVSOP87 // default package
// Software released under the General Public License (version 2 or later), available at
// http://www.gnu.org/copyleft/gpl.html
//*********************************************************************************

import java.io.*;
import java.util.*; // for Lists, Collections
import java.text.*;

/******************************************************************
Contains methods used to build VSOP87 data classes. The main method is <CODE>transformVSOP87()</CODE>.
<BR>This class is independant from <CODE>jephem</CODE> and <CODE>tig</CODE> packages, can be compiled separately.
<BR>JEphem program doesn't use it, it was just used to build JEphem.
<BR>It can be useful to developpers who want to transform BDL VSOP87 files.
<BR>In this class, when arrays characterizing planetary data were needed (ex : for "a0s",
"eccs"), the indexes of <CODE>jephem.astro.SolarSystemConstants.java were used</CODE>.

<BR><BR><B>Warning</B> : to make <CODE>transformVSOP87()</CODE> work, BDL files need to be checked ; 
if there are no terms for a couple {variable, power of time}, <I>there is no comment line in the BDL file</I>.
It is then necessary to add a comment line with "0 TERMS" in it (this problem occurs with Uranus and Neptune
in VSOP87A).
<BR>These modified data files must be in the current directory.


@author Thierry Graff
@history nov 07 2000 : Creation
@history dec 19 2000 : Start VSOP87Transform1
@history dec 25-29 2000 : Continue
@history jan 14 2001 : Fixed bugs and generate VSOP87A
@history jul 29 2001 : Adapted to handle different truncation methods (JEPHEM and BDL)
@history dec 16 2001 : Bettered details
@history feb 09 2002 : Added BINARY generation

@todo In commment of calcPrecision(), put address of chk file.
@todo In commment of calcPrecision(), put link to site output.
@todo see if calcErrMax and calcAlphaMax should directly be called by transformVSOP87.
@todo see if calcErrMax and calcAlphaMax must go to BuildVSOP87 or AnalyzeVSOP87.
@todo see if transformVSOP87 should take 'precision' as supplementary argument
@todo in calcErrMax javadoc, say if the result is in radians.
@todo integrate to transformVSOP the generation of nbTerms class
*****************************************************************/
public abstract class BuildVSOP87{

  //=================================================================================
  //                                 PUBLIC CONSTANTS
  //=================================================================================

  /** Argument to pass to <CODE>main()</CODE> to call <CODE>transformVSOP87()</CODE> */
  public static final String ARG_TRANSFORM = "transform";
  /** Argument to pass to <CODE>main()</CODE> to call <CODE>getBdlCommentLines()</CODE> */
  public static final String ARG_CALC_ERR_MAX = "calcErrMax";
  /** Argument to pass to <CODE>main()</CODE> to call <CODE>calcErrMax()</CODE> */
  public static final String ARG_GET_COMMENT_LINES = "getBdlCommentLines";
  /** Argument to pass to <CODE>main()</CODE> to call <CODE>calcAlphaMax()</CODE> */
  public static final String ARG_CALC_ALPHA_MAX = "calcAlphaMax";
  /** Argument to pass to <CODE>main()</CODE> to call <CODE>calcTotalNbTerms()</CODE> */
//  public static final String ARG_CALC_TOTAL_NB_TERMS = "calcTotalNbTerms";

  //=================================================================================
  //                                 PRIVATE CONSTANTS
  //=================================================================================

  // Some constants are repeated here to have the class independant from jephem package
  private static final String LS = System.getProperty("line.separator");
  private static final String BLANK = "";
  private static final int SPACE_CODE = 32; // Unicode code of " ".
  private static final int A_CODE = 10; // Unicode code of 'A'.
  private static final int BEGIN_ABC = 82; // Index between terms K and A in a data line of a BDL file.
  private static final int ALPHA_MAX = 5; // Maximum degree of time in VSOP87 BDL files.

  private static final String JAVA    = "JAVA";
  private static final String TEXT    = "TEXT";
  private static final String BINARY  = "BINARY";
  private static final String VSOP87  = "VSOP87";
  private static final String FULL    = "FULL";
  private static final String JEPHEM  = "JEPHEM";
  private static final String BDL     = "BDL";

  // must be 2 and 9 (if not, some code will bug).
  private static final int MERCURY = 2; // from jephem.astro.ISolarSystem.java
  private static final int NEPTUNE = 9; // from jephem.astro.ISolarSystem.java
  private static final double KM_PER_AU  = 149597870.61; // from jephem.astro.ISolarSystem.java
  /** Constant to convert radians to arc seconds, whose value is 180 * 3600 /
  <FONT FACE="symbol">p</FONT>. */
  public static final double RAD_TO_ARCSEC = 206264.806247096355156473357330779;

  /** Planet names ; indexes correspond to jephem.astro.ISolarSystem.java constants. */
  private static final String[] planetNames	= {"", "", "Mercury", "Venus", "Earth", "Mars", "Jupiter",
                                  "Saturn", "Uranus", "Neptune"};
  /** Semi-major axis ; index corresopnd to jephem.astro.ISolarSystem.java constants. */
  private static final double[] a0s = {0.0, 0.0, 0.3871, 0.7233, 1.00, 1.5237,
                                       5.2026, 9.5547, 19.2181, 30.1096}; // a.u.
  /** Eccentricities ; index corresopnd to jephem.astro.ISolarSystem.java constants. */
  private static final double[] eccs = {0.0, 0.0, 0.21, 0.01, 0.02, 0.09, 0.05, 0.06, 0.05, 0.01};

  /** Precision to reach (arc seconds) - used in transformVSOP87 with 'BDL' filter. */
  private static final double PRECISION = 1;

  /** Maximal geocentric angular error admissible for a planet (result of calcAlphaMax()).
  <BR>Valid for versions A and C.
  <BR>Indexes corresopnd to jephem.astro.ISolarSystem.java constants.
  <BR>Values are in arc seconds
  */
  private static final double alphaMax[] = {0.0, 0.0, 0.5, 0.1, 0.2, 0.4, 0.9, 0.9, 0.9, 0.9};

  //=================================================================================
  //                                 CONSRUCTORS
  //=================================================================================
  /** Useless as all the methods are static. */
  public BuildVSOP87(){}

  //=================================================================================
  //                                 METHODS
  //=================================================================================

  //**************** main ************************
  /** Dispatches the call to different methods, depending on first argument.
  @param args The first argument must be one of ARG_XXX constants ; indicates which method will be
  called. The following arguments are passed to the called method.
  */
  public static void main(String[] args){
    // paramater checking
    String argList = "'" + ARG_TRANSFORM + "' , '" + ARG_CALC_ERR_MAX + "', '"
                         + ARG_GET_COMMENT_LINES + "'"
                         + "' or '" + ARG_CALC_ALPHA_MAX + "'";
    if (args.length == 0){
      System.out.println("Call to main must have at least one argument :");
      System.out.println(argList);
      System.exit(0);
    }
    if (args[0].compareToIgnoreCase(ARG_TRANSFORM) == 0){
      if (args.length == 6)
        transformVSOP87(args[1], args[2], args[3], args[4], args[5]);
      else{
        System.out.println("transformVSOP87() needs 5 arguments - so call main with 6 arguments");
        System.exit(0);
      }
    }
    else if (args[0].compareToIgnoreCase(ARG_CALC_ERR_MAX) == 0)
      calcErrMax();
    else if (args[0].compareToIgnoreCase(ARG_GET_COMMENT_LINES) == 0)
      getBdlCommentLines();
    else if (args[0].compareToIgnoreCase(ARG_CALC_ALPHA_MAX) == 0){
      if (args.length == 3)
        calcAlphaMax(args[1], args[2]);
      else{
        System.out.println("calcAlphaMax() needs 2 arguments - so call main with 3 arguments");
        System.exit(0);
      }
    }
    else{
      System.out.println("First argument must be :");
      System.out.println(argList);
    }
    System.exit(0);
  }// end main

  //**************** TransformVSOP87 ************************
  /** Method to transform a VSOP87 data file for a particular planet.
  <BR>Produces a java class, an ASCII file or a binary file from a BDL original file (see parameter 'strOutputType').
  <BR>A selection of terms can be done or not (see parameter 'strFilter').

  <BR><BR>Example of call used to generate
  <CODE>jephem.astro.planets.vsop87.DataVSOP87A_JEphem_Earth.java</CODE> :
  <BR><CODE>VSOP87Transform("VSOP87A.ear.txt", "4", "A", "JEPHEM", "JAVA")</CODE> :
  'VSOP87A.ear.txt' designates the name of the original BDL file ; '4' designates the index
  of the planet (the Earth) ; 'JEPHEM' is the "filter" ; 'JAVA' tells that a java class must be generated.
  <BR>Example of call used to generate
  <CODE>jephem.astro.planets.vsop87.DataVSOP87A_Full_Earth</CODE> :
  <BR><CODE>VSOP87Transform("VSOP87A.ear.txt", "4", "A", "FULL", "BINARY")</CODE>

  @param inputFile name of BDL file containing data for the planet (must be in the current
  directory).

  @param strPlanetIndex Index of the planet, in coherence with
  <CODE>jephem.astro.ISolarSystem.java</CODE> constants (2 = Mercury ... 9 = Neptune).

  @param strVersion VSOP87 Version used ("A", "B", "C", "D" or "E"). To use raw VSOP87 version,
         <CODE>strVersion</CODE> must be "VSOP87".

  @param strFilter Indicates the method used to remove terms :
    
&nbsp;&nbsp;- "FULL" : no filter, all terms are retained. <BR>  - <CODE>"FULL"</CODE> : no filter, all terms are retained.
&nbsp;&nbsp;- "JEPHEM" : filter used for JEphem classes (see JEphem website <BR>  - <CODE>"JEPHEM"</CODE> : filter used for JEphem classes (see JEphem website for explanation).
&nbsp;&nbsp;- "BDL" : filter explained in astron. astroph. 202 p, 314. <BR>  - <CODE>"BDL"</CODE> : filter explained in astron. astroph. 202 p, 314. @param strOutputType Indicates what output file produce :
&nbsp;&nbsp;- "JAVA" : produces a java class. <BR>  - <CODE>"JAVA"</CODE> : produces a java class.
&nbsp;&nbsp;- "TEXT" : produces a text file containing the terms. <BR>  - <CODE>"TEXT"</CODE> : produces a text file containing the terms.
&nbsp;&nbsp;- "BINARY" : produces a binary file containing the terms. <BR>  - <CODE>"BINARY"</CODE> : produces a binary file containing the terms. */ public static void transformVSOP87(String inputFile, String strPlanetIndex, String strVersion, String strFilter, String strOutputType){ // ****** 1 - Parameter parsing ****** // planet index int planetIndex = Integer.parseInt(strPlanetIndex); if (planetIndex < MERCURY || planetIndex > NEPTUNE){ System.out.println("Invalid planet index"); return; } // version number int c = Character.getNumericValue(strVersion.charAt(0)); if (!strVersion.equals(VSOP87)){ if (c < A_CODE || c > A_CODE + 4){ System.out.println("Invalid version code - must be 'A', 'B', 'C', 'D', 'E' or 'VSOP87'"); return; } } String VSOPVersionNumber; // data lines of BDL files start with a digit depending on the version String strVersionForClassName; if (strVersion.equals(VSOP87)){ VSOPVersionNumber = "0"; strVersionForClassName = ""; } else{ VSOPVersionNumber = Integer.toString(c - A_CODE + 1); strVersionForClassName = strVersion; } // filter to retain terms if (!strFilter.equals(FULL) && !strFilter.equals(JEPHEM) && !strFilter.equals(BDL)){ System.out.println("Invalid filter - must be 'FULL', 'JEPHEM' or 'BDL'"); return; } // type of output if (!strOutputType.equals(JAVA) && !strOutputType.equals(TEXT) && !strOutputType.equals(BINARY)){ System.out.println("Invalid output type - must be 'JAVA', 'TEXT' or 'BINARY'"); return; } // ****** 2 - Prepare variables ****** String planetName = planetNames[planetIndex]; System.out.println("Building " + planetName + " data class or text file."); String className = "DataVSOP87" + strVersionForClassName + "_"; if (strFilter.equals(FULL)) className += "Full_"; if (strFilter.equals(JEPHEM)) className += "JEphem_"; if (strFilter.equals(BDL)) className += "BDL_"; className += planetName; String outputFileName = ""; if (strOutputType.equals(JAVA)) outputFileName = className + ".java"; if (strOutputType.equals(TEXT)) outputFileName = className + ".txt"; if (strOutputType.equals(BINARY)) outputFileName = className; // errMax, theErrMax are used only if strFilter == JEPHEM // TMax and TMaxAlpha are used only if strFilter == JEPHEM or BDL // errMax = maximal term to retain for A, T**0 // (result of a previous execution of calcErrMax()). double[] errMax = { 0.0, 0.0, 7.111045192663667E-7, // Mercury 7.076056778988369E-8, // Venus 5.486183262191636E-7, // Earth 4.0664933894487265E-7, // Mars 9.875129872004521E-6, // Jupiter 2.0045002140698977E-5, // Saturn 4.342789894476682E-5, // Uranus 7.252401182963036E-5, // Neptune }; double theErrMax = errMax[planetIndex]; // Maximal values of T (in millenia from JD2000) - from VSOP87.doc in BDL ftp. // (the interval of validity (then TMax) depends on the planet) int[] TMax = {0, 0, 4, 4, 4, 4, 2, 2, 6, 6}; // TMaxAlpha = Array of maximal values of T**alpha int[] TMaxAlpha = new int[ALPHA_MAX + 1]; TMaxAlpha[0] = 1; TMaxAlpha[1] = TMax[planetIndex]; for (int i = 2; i < ALPHA_MAX + 1; i++) TMaxAlpha[i] = TMaxAlpha[i-1] * TMaxAlpha[1]; String[] coordNames = {"X", "Y", "Z"}; int[][] nbTerms = new int[3][ALPHA_MAX + 1]; int coord, alpha; // current coord, degree of time. int itmp; // to parse comment and data lines. int counter; // counts data lines read from last comment line. int curNbTerms; // nb of terms for a couple (coord, alpha) in original file. int nbRetained; // nb of terms retained for a couple (coord, alpha). String strA, strB, strC; // contains String representations of A, B, C. double A; // term 'A'. // contains all curTerms for a given couple (coord, alpha) ; useful only if strFilter == BDL. // ****** 3 - parse input file ****** FileOutputStream fos = null; LineNumberReader lnr = null; ObjectOutputStream oos = null; // if the output is 'JAVA', a class header is written ; then String for data[][] is memorized in // strResJava2 ; at the end of parsing, it is possible to build nbTerms, which is written first. // if the output is 'TEXT', no need for decorations, the output is written directly during the // parsing; try{ fos = new FileOutputStream(new File(outputFileName)); lnr = new LineNumberReader(new FileReader(new File(inputFile))); oos = new ObjectOutputStream(fos); // Note : strResJava1 and 2 are necessary in order to have in the java class successivement 'nbTerms' and 'data' // StrBuff2 was used for performance reasons (strResJava2 is growing, and each '+' needs a reallocation). String line = new String(); String strResJava1 = new String(); // result String if the output is a java file String strResJava2 = new String(); // result String if the output is a java file StringBuffer strBuff2 = new StringBuffer(); // to store the value of strResJava2 line after line. String strResText = new String(); // result String if the output is a text file if (strOutputType.equals(JAVA)){ strResJava1 += "//********************************************************************" + LS; strResJava1 += "// class jephem.astro.planets.vsop87." + className + LS; strResJava1 += "// Software released under the General Public License (version 2 or later), " + "available at" + LS; strResJava1 += "// http://www.gnu.org/copyleft/gpl.html" + LS; strResJava1 += "//********************************************************************" + LS; strResJava1 += "package jephem.astro.planets.vsop87;" + LS; strResJava1 += LS; strResJava1 += "/********************************************************************" + LS; strResJava1 += "Data for calculation of " + planetName + " coordinates using VSOP87 theory"; strResJava1 += " (version " + strVersion + ")." + LS; strResJava1 += "********************************************************************/" + LS; strResJava1 += "class " + className + "{" + LS; strResJava1 += LS; fos.write(strResJava1.getBytes()); } if (strOutputType.equals(TEXT)){ strResText += "Data for calculation of " + planetName + " coordinates using VSOP87 theory"; strResText += " (version " + strVersion + ")." + LS + LS; fos.write(strResText.getBytes()); } if (strOutputType.equals(JAVA)){ strResJava2 = " /** Array containing the terms for the summation." + LS; strResJava2 += " <BR><CODE>data[n][0]</CODE> represents term A." + LS; strResJava2 += " <BR><CODE>data[n][1]</CODE> represents term B." + LS; strResJava2 += " <BR><CODE>data[n][2]</CODE> represents term C." + LS; strResJava2 += " */" + LS; strResJava2 += " protected static final double data[][] = {" + LS; strBuff2.append(strResJava2); strResJava2 = BLANK; } if (strOutputType.equals(BINARY)){ // Nada } // Initialize variables coord = itmp = counter = curNbTerms = nbRetained = 0; // initialize to please compiler... alpha = -1; A = 0.0; // MAIN LOOP - read line after line, write data[][] while((line = lnr.readLine()) != null){ line = line.trim(); if (strOutputType.equals(TEXT)) strResText = ""; //*** 3.1 - parse comment line if (line.startsWith(VSOP87)){ alpha++; if (alpha == ALPHA_MAX + 1){ alpha = 0; coord++; } System.out.println("parsing coord = " + coord + ", alpha = " + alpha); counter = 0; nbRetained = 0; if (strOutputType.equals(JAVA)) strResJava2 += " // " + planetName + " " + coordNames[coord] + ", " + "T**" + Integer.toString(alpha) + LS; else if (strOutputType.equals(TEXT)) strResText += "// " + planetName + " " + coordNames[coord] + ", " + "T**" + Integer.toString(alpha) + LS; // retrieve nbTerms[coord][alpha]; line = line.substring(line.indexOf("*T**") + 5).trim(); StringReader sr = new StringReader(line); StringWriter sw = new StringWriter(); while((itmp = sr.read()) != SPACE_CODE) sw.write(itmp); curNbTerms = Integer.parseInt(sw.toString()); sr.close(); sw.close(); if (curNbTerms == 0){ // end couple (coord, time) comment if (strOutputType.equals(JAVA)) strResJava2 += " // Originally 0 term, 0 term retained, 0 term dropped." + LS + LS; else if (strOutputType.equals(TEXT)) strResText += "// Originally 0 term, 0 term retained, 0 term dropped." + LS + LS; } } //*** 3.2 parse data line else if (line.startsWith(VSOPVersionNumber)){ // data line counter ++; //System.out.println("counter = " + counter); // keep only terms A, B, C from the line. line = line.substring(BEGIN_ABC).trim(); // read A itmp = line.indexOf(" "); strA = line.substring(0, itmp); A = Double.parseDouble(strA); // 'filtering' is done here for 'FULL', 'JEPHEM' and 'BDL' if( (strFilter.equals(FULL)) || (strFilter.equals(JEPHEM) && A * TMaxAlpha[alpha] > theErrMax) || (strFilter.equals(BDL) && 2*Math.sqrt(counter)*A*TMaxAlpha[alpha] > theErrMax) ){ // read B line = line.substring(itmp).trim(); itmp = line.indexOf(" "); strB = line.substring(0, itmp); // read C strC = line.substring(itmp).trim(); nbRetained ++; // write in strResXXX if (strOutputType.equals(JAVA)) strResJava2 += " { " + strA + ", " + strB + ", " + strC + " }," + LS; if (strOutputType.equals(TEXT)) strResText += strA + " " + strB + " " + strC + LS; if (strOutputType.equals(BINARY)){ // convert to double and write in the output oos.writeDouble(Double.parseDouble(strA)); oos.writeDouble(Double.parseDouble(strB)); oos.writeDouble(Double.parseDouble(strC)); } }// end if strFilter.equals ... //*** 3.3 End of a couple (coord, time) if (counter == curNbTerms){ nbTerms[coord][alpha] = nbRetained; // Write comment for the end of a couple (coord, time) if (strOutputType.equals(JAVA)) strResJava2 += " // Originally " + Integer.toString(curNbTerms) + " terms, " + Integer.toString(nbRetained) + " terms retained, " + Integer.toString(curNbTerms - nbRetained) + " terms dropped." + LS + LS; if (strOutputType.equals(TEXT)) strResText += "// Originally " + Integer.toString(curNbTerms) + " terms, " + Integer.toString(nbRetained) + " terms retained, " + Integer.toString(curNbTerms - nbRetained) + " terms dropped." + LS + LS; } // end if (counter == curNbTerms) }// end if (line.startsWith(VSOPVersionNumber) (parsing of a data line) // transfer strResJava2 in StringBuffer strBuff2.append(strResJava2); strResJava2 = BLANK; if (strOutputType.equals(TEXT)) fos.write(strResText.getBytes()); } // end MAIN LOOP strResJava2 = strBuff2.toString(); if (strOutputType.equals(JAVA)){ strResJava2 += " }; // end data[][]" + LS + LS; strResJava2 += "} // end class " + className + LS; // remove last coma itmp = strResJava2.lastIndexOf("},"); strResJava2 = strResJava2.substring(0, itmp+1) + strResJava2.substring(itmp+2); strResJava1 = ""; strResJava1 += " /** Array indicating the number of terms for a coordinate and a power of " + "time." + LS; strResJava1 += " <BR><CODE>nbTerms[i][j]</CODE> = number of terms for coordinate i "; strResJava1 += "(X, Y or Z)," + LS; strResJava1 += " for t<SUP>j</SUP>." + LS; strResJava1 += " */" + LS; strResJava1 += " protected static final int nbTerms[][] = {" + LS; for (int i= 0; i<3; i++){ strResJava1 += " {"; for (int j= 0; j==ALPHA_MAX; j++){ strResJava1 += Integer.toString(nbTerms[i][j]); if (j != ALPHA_MAX) strResJava1 += ", "; } if (i < 2) strResJava1 += "}," + LS; else strResJava1 += "}" + LS; } strResJava1 += " }; // end nbTerms[][]" + LS + LS; fos.write(strResJava1.getBytes()); // write nbTerms[][] fos.write(strResJava2.getBytes()); // write data[][] }// end if (strOutputType.equals(JAVA)) oos.close(); fos.close(); lnr.close(); } catch(Exception e){ // System.out.println("Exception" + e.toString()); e.printStackTrace(); System.exit(0); } }// end transformVSOP87() //**************** calcAlphaMax ************************ /** Intermediate calculation to know maximal geocentric angular error admissible for a planet to finally get 1 arcsecond of precision (only useful when JEphem truncation method is used). <BR>Used to fill 'errMax' array of <CODE>transformVSOP87()</CODE>, when JEphem truncation method is employed. @param strAlpha0 and strAlpha1 represent the values in arc seconds */ public static void calcAlphaMax(String strAlpha0, String strAlpha1){ double alpha0 = Double.parseDouble(strAlpha0); double alpha1 = Double.parseDouble(strAlpha1); alpha0 = Math.toRadians(alpha0/3600.0); alpha1 = Math.toRadians(alpha1/3600.0); double aE = a0s[4]; // earth semi-major axis double eccE = eccs[4]; // earth eccentricity. Could be bettered by calculating eccP and eccE // in validity interval, and take max / min values. double res = 0; // = SE/EP double alpha = 0; for(int pl = 2; pl < 10; pl++){ // pl = planetIndex if (pl == 4) continue; double aP = a0s[pl]; // planet semi-major axis double eccP = eccs[pl]; // planet eccentricity. switch (pl){ case 2: case 3: res = aE * (1 + eccE) / (aE*(1 - eccE) - aP*(1 + eccP)); break; case 4: break; default: res = aE * (1 + eccE) / (aP*(1 - eccP) - aE*(1 + eccE)); break; } alpha = alpha0 + Math.atan(res * Math.tan(alpha1)); alpha = Math.toDegrees(alpha) * 3600.0; System.out.println(planetNames[pl] + " : " + alpha); } // end for pl }// end calcAlphaMax() //**************** calcErrMax ************************ /** Calculation of maximal error in cartesian heliocentric position (only useful when JEphem truncation method is used). <BR>Results of calcAlphaMax are used (array alphaMax). <BR>Results written into a file ('errMax.txt') in order to incorporate to transformVSOP87 code. */ public static void calcErrMax(){ FileOutputStream fos = null; String strRes = ""; strRes += " double[] errMax = { 0.0, " + LS; strRes += " 0.0, " + LS; try{ fos = new FileOutputStream(new File("errMax.txt")); double errMax = 0; double v3 = Math.sqrt(3.0); double aE = a0s[4]; // earth semi-major axis double eccE = eccs[4]; // earth eccentricity. Could be bettered by calculating eccP and eccE // in validity interval, and take max / min values. double res = 0; double alpha = 0; for(int pl = 2; pl < 10; pl++){ // pl = planetIndex double aP = a0s[pl]; // planet semi-major axis double eccP = eccs[pl]; // planet eccentricity. double tgAlphaMax = Math.tan(Math.toRadians(alphaMax[pl]/3600.0)); switch (pl){ case 2: case 3: errMax = (aE*(1 - eccE) - aP*(1 + eccP)) * tgAlphaMax / v3; break; case 4: errMax = aE*(1 - eccE) * tgAlphaMax / v3; break; default: errMax = (aP*(1 - eccP) - aE*(1 + eccE)) * tgAlphaMax / v3; break; } System.out.println(planetNames[pl] + " : " + errMax); strRes += " " + Double.toString(errMax) + ", "; strRes += " // " + planetNames[pl] + LS; } // end for pl strRes += " };" + LS; fos.write(strRes.getBytes()); fos.close(); } catch(Exception ex){ System.out.println("Exception" + ex.toString()); ex.printStackTrace(); System.exit(0); } }// end calcErrMax() //**************** getBdlCommentLines() ************************ /** Produces an output with only comment lines of BDL files. <BR>Method used to check validity of nbTerms arrays in classes "DataVSOP87C_Full_xxx". <BR>Input files must be in the current directory. The input files must be called <B>VSOP87X.xxx.txt</B> (ex : "VSOP87C.ear.txt") with X = version letter ; xxx = planet short name. */ public static void getBdlCommentLines(){ String strOutputFile = "DataVSOP87C_Comments.txt"; String[] strInputFiles = {"VSOP87C.ear.txt", "VSOP87C.jup.txt", "VSOP87C.mar.txt", "VSOP87C.mer.txt", "VSOP87C.nep.txt", "VSOP87C.sat.txt", "VSOP87C.ura.txt", "VSOP87C.ven.txt" }; FileOutputStream fos = null; LineNumberReader lnr = null; try{ fos = new FileOutputStream(new File(strOutputFile)); String line = new String(); for (int i = 0; i < strInputFiles.length ; i++){ lnr = new LineNumberReader(new FileReader(new File(strInputFiles[i]))); while((line = lnr.readLine()) != null){ if (line.trim().startsWith(VSOP87)){ fos.write(line.getBytes()); fos.write(LS.getBytes()); } } // end while((line = lnr.readLine()) != null) fos.write(LS.getBytes()); lnr.close(); lnr = null; } // end for i < strInputFiles.length fos.close(); } catch(Exception e){ System.out.println("Exception" + e.toString()); e.printStackTrace(); System.exit(0); } }// end getBdlCommentLines() private static final DecimalFormat NF = new DecimalFormat(); private static final DecimalFormat NF2 = new DecimalFormat(); static{ NF.setMaximumFractionDigits(1); NF.setMinimumFractionDigits(1); NF2.setMaximumFractionDigits(4); NF2.setMinimumFractionDigits(4); DecimalFormatSymbols dfs = new DecimalFormatSymbols(); dfs.setDecimalSeparator('.'); NF.setDecimalFormatSymbols(dfs); NF2.setDecimalFormatSymbols(dfs); }; }//end class BuildVSOP87