//*********************************************************************************
// 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 :
- "FULL"
: no filter, all terms are retained. <BR> - <CODE>"FULL"</CODE> : no filter, all terms are retained.
- "JEPHEM"
: filter used for JEphem classes (see JEphem website <BR> - <CODE>"JEPHEM"</CODE> : filter used for JEphem classes (see JEphem website
for explanation).
- "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 :
- "JAVA"
: produces a java class. <BR> - <CODE>"JAVA"</CODE> : produces a java class.
- "TEXT"
: produces a text file containing the terms. <BR> - <CODE>"TEXT"</CODE> : produces a text file containing the terms.
- "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